zoukankan      html  css  js  c++  java
  • Windows Phone 7 学习志(常见问题一:不能直接修改按钮Button背景色或前景色)

    这个问题对于初学者估计是个蛮大的问题,至少我当初就是这样,听到同事说点击按钮事件中按钮前景色无法修改,心里十分纳闷,这怎么可能呢?可是当自己新建了一个页面,加了一个按钮和一个点击事件后,事实还就真的发生了。

      前台按钮代码:

    <Button Content="Button" Background="Blue" Click="button1_Click" Height="173" HorizontalAlignment="Left" Margin="94,70,0,0" Name="button1" VerticalAlignment="Top" Width="267"/>

     

      为了看的明白点,把按钮背景色先设成了Blue,其他参数都可以无视。

      后台CS代码增加按钮事件:

     

    privatevoid button1_Click(object sender, RoutedEventArgs e)
    {
    button1.Background
    =new SolidColorBrush(Colors.Red);
    }

      运行程序,点击按钮,的确一点反应都没有,那是为什么呢?想来无非那几种情况:

    第一:值没有真正传入属性。

    第二:难道和网页一样,需要刷新才能传值成功?

    第三:存在内部其他机制。

      我们一个个来分析。

    第一:把button1.Background = new SolidColorBrush(Colors.Red);放入画面初始化方法InitializeComponent()的后面,运行后,颜色改变,说明传值不存在问题。

    第二:我表示我不知道刷新方法是哪个,要是读者知道可以告诉我。

    第三:既然前两个都是未知,那必然这个原因嫌疑最大了。

    遇到该问题时我查询了MSDN上WP7专区的疑问解答,有个链接把我指向了http://blogs.msdn.com/b/ptorr/archive/2010/06/18/why-can-t-i-change-the-background-of-my-button-on-a-click-event.aspx

      简单说明下该文章说明的关键:Silverlight使用VisualStateManager来显示不同的视觉状态(像普通,被按住等等动作),桌面版本的Silverlight的控制模板比手机中使用控制模板要复杂的多,所以桌面版本的Silvelight没有这个问题。

      那什么是VisualStateManager呢,是前台的设置还是后台的设置呢?

      先上示例:http://samples.msdn.microsoft.com/Silverlight/SampleBrowser/index.htm#/?sref=CustomTemplateSamples&id=3

      打开后是一个Silverlight Sample,鼠标放到按钮上然后移开有不同的效果,其实在WP7上也有一样的效果,只不过是按住鼠标后经过按钮有效果。点击上方的view sample source code,可以看到xaml文件里满满当当,cs文件里几乎没有代码,仅有的代码也和主题无关。

    如此满满当当的代码自然理解起来非常难,想系统理解的可以去看“通过使用 ControlTemplate 自定义现有控件的外观”:http://msdn.microsoft.com/zh-cn/library/cc189093(v=VS.95).aspx

      回到正题,如何才能实现点击后改变背景色和前景色呢?

    关键部分:借助Visual State Manager,自定义一个按钮模板,这样就可以对应用模板的按钮的参数进行修改。

    下面是个按钮的基础模板文件(取自前面提到的一个网页里),我用绿颜色标注了下修改部分。先扫一遍,然后我会说这么昂长的代码哪里可以获得。总不见要自己输入对吧。

     

    代码
    <Button Content="Click Me" x:Name="ClickMe" Click="ClickMe_Click" Background="Red">
    <Button.Template>
    <ControlTemplate TargetType="Button">
    <Grid Background="Transparent">
    <VisualStateManager.VisualStateGroups>
    <VisualStateGroup x:Name="CommonStates">
    <VisualState x:Name="Normal"/>
    <VisualState x:Name="MouseOver"/>
    <VisualState x:Name="Pressed">
    <Storyboard>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer"
    Storyboard.TargetProperty
    ="Foreground">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneBackgroundBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="PressedHighlightBackground"
    Storyboard.TargetProperty
    ="Background">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground"
    Storyboard.TargetProperty
    ="BorderBrush">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneForegroundBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    </Storyboard>
    </VisualState>
    <VisualState x:Name="Disabled">
    <Storyboard>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ContentContainer"
    Storyboard.TargetProperty
    ="Foreground">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground"
    Storyboard.TargetProperty
    ="BorderBrush">
    <DiscreteObjectKeyFrame KeyTime="0" Value="{StaticResource PhoneDisabledBrush}"/>
    </ObjectAnimationUsingKeyFrames>
    <ObjectAnimationUsingKeyFrames Storyboard.TargetName="ButtonBackground"
    Storyboard.TargetProperty
    ="Background">
    <DiscreteObjectKeyFrame KeyTime="0" Value="Transparent"/>
    </ObjectAnimationUsingKeyFrames>
    </Storyboard>
    </VisualState>
    </VisualStateGroup>
    </VisualStateManager.VisualStateGroups>
    <Border x:Name="ButtonBackground" BorderBrush="{TemplateBinding BorderBrush}"
    BorderThickness
    ="{TemplateBinding BorderThickness}" CornerRadius="0"
    Background
    ="{TemplateBinding Background}" Margin="{StaticResource PhoneTouchTargetOverhang}">
    <Border x:Name="PressedHighlightBackground" Background="Transparent">
    <ContentControl x:Name="ContentContainer" Foreground="{TemplateBinding Foreground}"
    HorizontalAlignment
    ="{TemplateBinding HorizontalContentAlignment}"
    VerticalAlignment
    ="{TemplateBinding VerticalContentAlignment}" Padding="{TemplateBinding Padding}"
    Content
    ="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}"/>
    </Border>
    </Border>
    </Grid>
    </ControlTemplate>
    </Button.Template>
    </Button>

     

     

     

      乍看一下,属性分支很多,很乱。我们暂且不纠结与这个代码,要我说的话,也就是增加了一个背景属性和一个边框,然后把背景属性指向了边框,把原先背景设成了透明。如果再重新在后台进行背景色的修改,你会发现,成功了。但是前景色怎么弄呢?而且偶尔每个按钮都要这么长的前台代码未免太麻烦了吧,况且如果按钮是自动生成的话怎么办呢,所以刚才让你系统的去看那篇“通过使用 ControlTemplate 自定义现有控件的外观”也是必要的,里面讲到很多不同的实现方法。

      接下来我来讲一下模板代码的来源,如果你是正常安装开发工具环境的话,你应该还记得那个Microsoft Expression Blend 4吧,那个UI设计工具。运用这个工具,你可以简单的获取和制作控件模板。打开程序后,新建一个项目,然后左半边内容如下图:

      点击Assets标签,从中拖一个按钮控件到页面中,画面左下角对象里多出一个Button,右键Button,点击Edit Template – Edit a Copy,弹出对话框,自己填写要保存的样式名字,然后确定,你会发现左下角变了,右键任何一个对象然后点View XAML可以查看前台代码。然后你点击左上角的States,会发现里面多出很多东西。

      这其实是原始模板按钮的状态行为,有兴趣的可以自己去找Expression Blend 4的相关教程,这个教程可比WP7教程多得多。举个例子,你想点击按钮后,按钮前景色变成自己想要的,并且不想按钮下次再能点击,你直接在点击按钮操作方法里把按钮的IsEnabled属性设成false就可以了,因为false状态下的前景色你可以在Expression Blend 4中的States的Disabled状态进行方便的设置,然后你只要把自己想要的那段Style代码复制到前台里,在需要使用的按钮属性中加上一条Style属性即可。就此这个方法的介绍就此结束。

      总结一下:今天的主题是前台的Visual State Manager,虽然后台代码相比前台更亲近我们,但这次前台的的确确做了很大的贡献,我觉得既然修改如此麻烦,必然以后就会有改变。当然我也不能说我介绍的这个方法就是最好的,如果有更好的,希望能告诉我,因为现在做的程序里用到这方面其实还蛮多的。初学者有空的还是像我说的多去我上篇日志介绍的MSDN的论坛搜索问题,虽然全是E文,但是帮助很大,比如你觉得Foreground不能修改,你关键字打Foreground就可以了。今天这篇写的比较急,也有点乱,觉得哪里有问题的希望大家多提出来。

    作者:Le Ruin
    出处:http://www.cnblogs.com/leluyun/
    关于作者:专注于Windows Phone 开发
    Windows Phone Store上不再有作者独立开发的程序,但作者依然还在开发的路上前行。
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,如有问题,可以通过新浪微博 leluyun@hotmail.com 联系我,非常感谢。

  • 相关阅读:
    vue-loader介绍和单页组件介绍
    webpack的插件 http-webpack-plugin。 webpack-dev-server
    webpack的介绍
    Axios 的基本使用
    如何使用 re模块的, spilt.
    为 JS 的字符串,添加一个 format 的功能。
    另一种分页器 不依赖Paginator模块的方法
    Socket初识
    网络协议
    双下方法补充以及异常处理
  • 原文地址:https://www.cnblogs.com/leluyun/p/1949914.html
Copyright © 2011-2022 走看看