在开发Windows Phone 7应用程序时,偶尔会需要实现带有两种状态的按钮,点击按钮即可在两种状态间进行切换,且各状态对应的外观也有所不同。其实SDK里默认自带的CheckBox控件及Silverlight Toolkit里提供的ToggleSwitch控件都能在某种程度上满足上述需求。只是它们的外观相对固定,并不容易定制。那么,今天就向大家介绍一款新的自定义控件,称之为:SwitchButton

 

首先,我们来看一看实际运行的效果:

Windows Phone 7 定制控件 - SwitchButton _自定义控件

在点击SwitchButton时,按钮的外观平滑地从左边的状态过渡到右边的状态,并且在代码中触发其Checked/Unchecked事件,并实时更新其IsChecked属性为truefalse

下载代码

接下来,我们就开始动手实现它。

 

第一步:编写自定义控件类

制作一个自定义的控件,首先要从编写控件的类开始。尽管我们要做的SwitchButtonCheckBox有所区别,但其主要的行为和属性应该是与CheckBox相一致的。因此,我们不妨先查看一番CheckBox的定义。在VisualStudio里通过追溯基类我们可以了解到,CheckBox是继承自System.Windows.Controls.Primitives命名空间下的ToggleButton类。进一步查看ToggleButton类的定义,可以看到一个带有状态的按钮所需要的大部分属性和事件,都是在这里进行定义的。既然如此,那我们的SwitchButton类也理所当然地要继承ToggleButton类。

Visual Studio里,创建(或打开)一个 Windows Phone 7 项目,然后添加一个SwitchButton类。代码如下:

public class SwitchButton : ToggleButton
{
    public static readonly DependencyProperty SwitchOnImageSourceProperty =
        DependencyProperty.Register(
        "SwitchOnImageSource",
        typeof(ImageSource),
        typeof(SwitchButton),
        null);

    public ImageSource SwitchOnImageSource
    {
        get { return (ImageSource)GetValue(SwitchOnImageSourceProperty); }
        set { SetValue(SwitchOnImageSourceProperty, value); }
    }

    public static readonly DependencyProperty SwitchOffImageSourceProperty =
        DependencyProperty.Register(
        "SwitchOffImageSource",
        typeof(ImageSource),
        typeof(SwitchButton),
        null);

    public ImageSource SwitchOffImageSource
    {
        get { return (ImageSource)GetValue(SwitchOffImageSourceProperty); }
        set { SetValue(SwitchOffImageSourceProperty, value); }
    }
}

我们在SwitchButton类中声明了两个属性,分别是:SwitchOnImageSourceSwitchOffImageSource。这两个属性用来指定SwitchButton控件在处于两种状态时所需要显示的外观图片。关于控件属性的声明,请查看有关 DependencyProperty 的更多信息。

 

第二步:设计自定义控件的外观和行为

Phone Page中拖放一个SwitchButton控件。然后用[右键单击]->[Edit Template]->[Edit a copy]的方式,生成一个模板。接下来,我们就开始编辑这个模板。

(关于在Expression Blend里设计自定义控件模板的详细步骤,请参考我的另外一篇文章:

Windows Phone 7 定制控件 - ImageButton

这里仅针对SwitchButton特有的内容进行说明。

 

SwitchButton的模板继承自ToggleButton控件的模板,具有三个VisualStateGroup,分别是:CommonStatesCheckStatesFocusStates。我们主要关心的是CheckStates状态组下的三个VisualState,分别是:CheckedUncheckedIndeterminate。其中,Indeterminate状态对应的是不确定状态,即在某些特殊应用场景中,需要实现三种状态的按钮时才用得到。在本例中,我们不去考虑它。

Windows Phone 7 定制控件 - SwitchButton _ 开关按钮_02

 

简单说明一下设计思路:在SwitchButton处于Checked状态时,我们需要它显示某个图片,而在它处于Unchecked状态时,我们需要它显示另一个图片。

OK,下面介绍具体操作步骤:

 

操作2.1

既然先后需要切换两个图片,那么就将控件模板根目录中Grid的所有子控件删除,并且加上两个Image控件,分别命名为:p_w_picpathOnp_w_picpathOff

Windows Phone 7 定制控件 - SwitchButton _休闲_03

 

操作2.2

选中p_w_picpathOn控件,在属性面板中,点击 [Source] 属性右侧的小方块(Advanced Options),设置 Template Binding SwitchOnImageSource。同样地,将p_w_picpathOff控件的Source绑定到SwitchOffImageSource属性。这一步操作,是将两个 Image控件的图片资源绑定到我们在一开始声明的两个属性上,从而实现在实际使用 SwitchButton 控件的地方,根据需求来指定不同的图片,达到重复使用的目的。

Windows Phone 7 定制控件 - SwitchButton _休闲_04

提示:

两个状态所对应的图片应遵循“大同小异”的原则,即:两张图的尺寸及配色基本一致,只有某一局部在位移、尺寸或明暗度上发生小幅变化。有些朋友或许会担心“变化不够大,怕用户忽略”,其实不然。请记住,用户的实现集中一处时,对哪怕一个像素的变化都是敏感的。

 

操作2.3

在默认状态下(即:在States面板中选中Base状态的情况下),将p_w_picpathOffOpacity值设置为0%,即不可见。

 

操作2.4

States面板中,选中Unchecked状态,将p_w_picpathOnOpacity设置为0%,而p_w_picpathOffOpacity设置为100%。然后将CheckStates下的Default transition设置为一个合理时长,例如0.3秒,从而使得状态间的切换过渡更加自然。

 

第三步:使用自定义控件

PhonePage中,放置一个SwitchButton控件并选中,然后在属性面板的Miscellaneous区域中,找到SwitchOnImageSource属性及SwitchOffImageSource属性。分贝为它们设置不同的图片,以代表两个状态。

Windows Phone 7 定制控件 - SwitchButton _Windows Phone 7_05

 

运行程序,在界面中反复点击SwitchButton按钮,会看到它在两个状态间进行切换。

Windows Phone 7 定制控件 - SwitchButton _自定义控件_06 

 

OK。至此我们就完成了定制SwitchButton控件。

下载代码


作者: 李靖南

出处:http://elecpiano.blog.51cto.com/   

Email: elecpiano@gmail.com 

新浪微博: http://weibo.com/zengnami

MSN: zengnami@hotmail.com

QQ: 52717278 


关于作者:

从事微软平台解决方案的设计与实现。主要专注于 Windows 8 及 Windows Phone 7 应用开发,及前者与微软云计算平台(Azure)的结合。

 

本文版权归作者和51CTO共有,欢迎转载,但未经作者同意则必须保留此段声明,并在文章较明显位置给出原文连接。非常感谢!