(一)创建默认控件模板
要求开发人员使用您的控件定义他们自己的控件模板是不合理的。自定义控件应具有默认的模板,提供默认模板后,人们仍可以使用其他模板,将其覆盖,但如果不要求提供模板,您的控件会更加吸引人。
(1)向控件项目添加名为 Generic.xaml 的文件。(是的,此文件必须命名为 Generic.xaml。大小写无关紧要,但文件名不能改变。)
(2)在 Generic.xaml 中定义样式,该样式使用属性 setter 将值分配给控件的 Template 属性.
Silverlight 运行时自动在控件程序集(Generic.xaml 作为数据源嵌入其中)中查找 Generic.xaml 并将样式应用到控件实例
这里以SimpleButtonDemo为例说明,自定义控件。
在 Generic.xaml 中添加代码如下
<ResourceDictionary
xmlns="/winfx//xaml/presentation"
xmlns:x="/winfx//xaml"
xmlns:custom="clr-namespace:SimpleButtonDemo;assembly=SimpleButtonDemo">
<Style TargetType="custom:SimpleButton">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="custom:SimpleButton">
<Grid x:Name="RootElement">
<Rectangle x:Name="BodyElement" Width="200" Height="100"
Fill="Lavender" Stroke="Purple" RadiusX="16" RadiusY="16" />
<TextBlock Text="Click Me" HorizontalAlignment="Center"
VerticalAlignment="Center" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
在SimpleButton.cs 并将以下语句添加到类构造函数
this.DefaultStyleKey = typeof(SimpleButton);
(二)添加模板绑定TemplateBinding
以上有个问题,我们若用下面的代码改变控件宽度,高度,会有以下问题!,该控件仍然是上面Rectangle宽 200,高 100,因为这些值已硬编码到控件模板中。
<custom:SimpleButton Width="250" Height="150" />
(1)模板绑定TemplateBinding的好处
模板绑定:允许分配给控件的属性值向下传递到控件模板,并且是使用 {TemplateBinding} 标记扩展在 XAML 中声明的。
Width="{TemplateBinding Width}" Height="{TemplateBinding Height}"
(三)ContentPresenter
(1)从 ContentControl 派生的自定义控件意味着它具有 Content 属性,在这钟情况下,我们常常用ContentPresenter替换TextBlock。因为TextBlock 只能呈现文本,而 ContentPresenter 可以呈现分配给此控件的 Content 属性的任何 XAML。
(2)现在,SimpleButton 支持两个自定义级别。可以使用自定义模板重新定义其整个可视树,或者仅使用 Content 属性重新定义其内容。而且,您还可以使用简单的 Content 属性更改按钮文本。SimpleButton 的行为越来越接近真正的按钮控件。
<ResourceDictionary
xmlns="/winfx//xaml/presentation"
xmlns:x="/winfx//xaml"
xmlns:custom="clr-namespace:SimpleButtonDemo;assembly=SimpleButtonDemo">
<Style TargetType="custom:SimpleButton">
<Setter Property="Width" Value="200" />
<Setter Property="Height" Value="100" />
<Setter Property="Background" Value="Lavender" />
<Setter Property="FontSize" Value="11" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="custom:SimpleButton">
<Grid x:Name="RootElement">
<Rectangle x:Name="BodyElement"
Width="{TemplateBinding Width}"
Height="{TemplateBinding Height}"
Fill="{TemplateBinding Background}"
Stroke="Purple" RadiusX="16" RadiusY="16" />
<ContentPresenter Content="{TemplateBinding Content}"
HorizontalAlignment="Center" VerticalAlignment="Center"
FontSize="{TemplateBinding FontSize}" />
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
(四)添加 Click 事件
在 Siverlight 中,事件只能向上传递,即“冒泡”操作。路由事件由 RoutedEventHandler 委托定义,并且路由事件处理程序接收 RoutedEventArgs 对象,该对象包含用于确认引发此事件的对象的 Source 属性(如果此事件最初由可视树中的深层对象引发,则该属性不同于传递给事件处理程序的发送者参数)。内置 Button 控件的 Click 事件是一个路由事件,因此 SimpleButton 的 Click 事件也应该是路由事件。
public class SimpleButton : ContentControl
{
public event RoutedEventHandler Click;
public SimpleButton()
{
this.DefaultStyleKey = typeof(SimpleButton);
this.MouseLeftButtonUp += new MouseButtonEventHandler
(SimpleButton_MouseLeftButtonUp);
}
void SimpleButton_MouseLeftButtonUp(object sender,
MouseButtonEventArgs e)
{
if (Click != null)
Click(this, new RoutedEventArgs());
}
}
(五)添加可视状态
(1)Silverlight 控件的两个主要组件是可视状态和可视状态转换。可视状态用于定义控件在不同状态下的外观:在处于按下、鼠标点击、禁用等状态时的外观。可视状态转换用于定义控件如何从一种可视状态转换到另一种可视状态:例如,从“正常”状态转换到“按下”状态。 (2)视觉状态管理器 (VSM),您可以使用 VisualState 对象封装 Storyboards 以定义状态,使用 VisualTransition 对象定义转换。然后,您可以使用 VisualStateManager 类的静态 GoToState 方法将控件转换到指定的状态以响应用户操作。
参考链接:
为 Silverlight 2 创建自定义控件