×
Namespaces

Variants
Actions

Windows Phone创建Custom Control(1)

From Nokia Developer Wiki
Jump to: navigation, search
WP Metro Icon UI.png
SignpostIcon WP7 70px.png
Article Metadata

代码示例
兼容于
文章
WS - OtomiiLu 在 05 Sep 2012 创建
最后由 hamishwillee 在 03 Jul 2013 编辑

本文主要是描述如何创建一个继承自Button控件的Custom Control。

Contents

什么是Custom Control

在很多场景中,我们需要创建Usercontrol或者Custom Control来完成来赋予一个个体拥有一些特性,以便我们方便地实现一些功能。 同时,Usercontrol和Custom Control又不相同,Usercontrol就像是把已经拥有的Control进行一种组合,比如登录框的Usercontrol一般情况下就是把两个TextBlock+两个Button的组合形成的,这种组合式的,就叫做Usercontrol,而Custom Control则是继承自Control的控件。

Custom Control的创建

继承自Button

首先,创建一个CusButton,

public class CusButton : Button

然后创建一个DependencyProperty的Color属性,以用来提供背景的绑定,DependencyProperty和普通的属性的区别为,DependencyProperty属性可以为值表达式、数据绑定、动画和属性更改通知提供支持。 举个例子,如果你声明了一个Style,你可以通过

<Setter Property="Background" Value="Red"/>

的形式来设置背景色,因为Background是DependencyProperty属性,但是你不能对一般的属性进行同样的操作,因为他们不是DependencyProperty属性。 在这里,我们提供了一个DependencyProperty属性ShadowColor:

public static readonly DependencyProperty ShadowColorProperty = 
DependencyProperty.Register(
"ShadowColor", typeof(Color),
typeof(CusButton), new PropertyMetadata(Colors.Red, new PropertyChangedCallback(OnShadowColorChanged))
);
public Color ShadowColor
{
get { return (Color)GetValue(ShadowColorProperty); }
set { SetValue(ShadowColorProperty, value); }
}
public static void OnShadowColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}

DependencyProperty属性的创建分为三步曲,第一步为声明,第二步为创建一个getset,第三步为创建一个Changed方法。 最后,我们会在CusButton的构造函数中加载在下一小节中创建好的Template:

public CusButton() 
{
base.DefaultStyleKey = typeof(CusButton);
}

只需要使用以上语句,程序就会自动在Themes\generic.xaml中获取到CusButton的界面的定义。 这样,基本的Button空间的代码部分就已经创建完毕了,代码部分主要会处理一些逻辑,全部代码如下:

public class CusButton : Button 
{
public static readonly DependencyProperty ShadowColorProperty =
DependencyProperty.Register(
"ShadowColor", typeof(Color),
typeof(CusButton), new PropertyMetadata(Colors.Red, new PropertyChangedCallback(OnShadowColorChanged))
);
public Color ShadowColor
{
get { return (Color)GetValue(ShadowColorProperty); }
set { SetValue(ShadowColorProperty, value); }
}
public CusButton()
{
base.DefaultStyleKey = typeof(CusButton);
}
public static void OnShadowColorChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
}
}

扩展Template

在定义了后台代码后,那么后面就该定义界面了,不同于一般的程序,在Windows Phone中定义界面有不同的方式。我们只需要定义XAML视图就可以为Windows Phone的程序定义我们所需要的界面 首先,在Project中创建Themes文件夹,然后在Themes创建generic.xaml文件,这个文件默认为Custom control获取界面的地方。 现在,来看下我定义的界面的全部XAML代码:

<Style TargetType="local:CusButton"> 
<Setter Property="Content" Value="CustomEffectButton"/>
<Setter Property="Background" Value="Red"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="local:CusButton">
<Grid>
<win:VisualStateManager.VisualStateGroups>
<win:VisualStateGroup x:Name="CommonStates">
<win:VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="1" Duration="0:0:0.5"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="1" Duration="0:0:0.5"></DoubleAnimation>
</Storyboard>
</win:VisualState>
<win:VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="2" Duration="0:0:0.5"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="2" Duration="0:0:0.5"></DoubleAnimation>
</Storyboard>
</win:VisualState>
<win:VisualState x:Name="Disabled">
</win:VisualState>
</win:VisualStateGroup>
</win:VisualStateManager.VisualStateGroups>
<ContentPresenter x:Name="contentPresenter">
<ContentPresenter.RenderTransform>
<ScaleTransform CenterX="40" CenterY="20" x:Name="scaleTransform" ScaleX="1" ScaleY="1"/>
</ContentPresenter.RenderTransform>
<Grid>
<Grid.Background>
<SolidColorBrush Color="{Binding ShadowColor,RelativeSource={RelativeSource TemplatedParent}}"/>
</Grid.Background>
<TextBlock Text="{TemplateBinding Content}">
</TextBlock>
</Grid>
</ContentPresenter>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

在代码中,首先我定义了VisualStateManager.VisualStateGroup,这个是主要用来改变状态的。 每个控件有自己的状态,因为我们定义的CusButton控件是继承自Button,所以,可以继承Button的VisualStateGroup,Button的VisualStateGroup定义如下:

[TemplateVisualState(Name = "Disabled", GroupName = "CommonStates")] 
[TemplateVisualState(Name = "Focused", GroupName = "FocusStates")]
[TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Pressed", GroupName = "CommonStates")]
[TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")]
public class Button : ButtonBase

我们选用了其中几个,然后对变化状态的时候,进行动画改变:

<win:VisualState x:Name="Normal"> 
<Storyboard>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="1" Duration="0:0:0.5"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="1" Duration="0:0:0.5"></DoubleAnimation>
</Storyboard>
</win:VisualState>
<win:VisualState x:Name="MouseOver">
<Storyboard>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleX" To="2" Duration="0:0:0.5"></DoubleAnimation>
<DoubleAnimation Storyboard.TargetName="scaleTransform" Storyboard.TargetProperty="ScaleY" To="2" Duration="0:0:0.5"></DoubleAnimation>
</Storyboard>
</win:VisualState>

接着是ContentPresenter元素,这个元素主要对于Button的Content属性进行定义。 同时,内部元素通过TemplateBinding来帮定父模版的元素:

<TextBlock Text="{TemplateBinding Content}">

这样子,我们的界面也定义完毕了。这种方式就是为Windows Phone定义Custom control的大致流程和方式,希望可以起到帮助作用。

使用控件

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0"> 
<customButton:CusButton ShadowColor="Red" Height="23" HorizontalAlignment="Left" Margin="10,43,0,0" VerticalAlignment="Top" Width="200" />
</Grid>

项目截图: CustomEffectButton.jpg

项目源文件: File:CustomEffectButton.zip

This page was last modified on 3 July 2013, at 06:48.
100 page views in the last 30 days.
×