这次通过最近做的小例子说明一下自定义Button控件和样式。
实现的效果为:
在讲解之前先分析一下:
这上面为八个按钮,这是毫无疑问的。在每个按钮中又包含了一个图片和文本两个元素。虽然有这么多按钮,但他们的样式基本相同,除了按钮中的图片和文字内容。所以我们可以把相同的部分提取出来,把不同的内容进行传参来实现不同的效果。
继续分析,在按钮中包含的这两个元素,一个是图片元素,一个是文本元素。先说文本元素,文本元素直接可以通过Button.Content直接赋值。但Image控件的Source属性不能通过Button中任何一个属性给它赋值。所以想 如果Button有个像Image控件一样的Source属性,并通过这两个进行Binding,那么这两个元素就都可以通过Button自身的属性就可以直接赋值。分析结果:
①要先自定义一个MyButton类,继承自Button。 给MyButton注册一个依赖属性 ImgSourceProperty,类型为ImageSource。这个Image控件的Source属性基本一样。
/// <summary>
/// 自定义Button控件
/// </summary>
public class MyButton:Button
{
//定义Imagesource依赖属性
public static readonly DependencyProperty ImgSourceProperty = DependencyProperty.Register
("ImgSource", typeof(ImageSource), typeof(MyButton), null);
public ImageSource ImgSource
{
get { return (ImageSource)GetValue(ImgSourceProperty); }
set { SetValue(ImgSourceProperty, value); }
}
}
②定义一个通用样式,在这里定义的样式其实是修改了Button模板
<Application x:Class="Test13.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:Test13" //要注意引用你自定义控件的命名控件
StartupUri="MainWindow.xaml">
<Application.Resources>
<Style x:Key="sysStatusButton"
TargetType="{x:Type local:MyButton}">
<Style.Setters>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:MyButton}">
<Border x:Name="border"
BorderBrush="{TemplateBinding Control.BorderBrush}"
BorderThickness="0"
Background="#2d548e"
CornerRadius="5,5,5,5">
<StackPanel Orientation="Horizontal">
<Image VerticalAlignment="Center"
Width="27"
Height="27"
Margin="5,0,0,0"
Source="{TemplateBinding ImgSource}"></Image> //这里把模板中Image控件的source属性Binding到自定义控件的ImgSource属性上。
<TextBlock VerticalAlignment="Bottom"
x:Name="textBlock"
Margin="5,0,0,7"
FontSize="12"
Foreground=" White"
Text="{TemplateBinding Content}"></TextBlock> //这里的文本控件直接绑定的是Button的Content内容。
</StackPanel>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter TargetName="border" Property="Border.Background" Value="#FF9900" />
<Setter TargetName="textBlock" Property="TextBlock.Foreground" Value="black" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style.Setters>
</Style>
</Application.Resources>
</Application>
③接下来就是在XAML中声明控件,当给自定义控件的这两个属性赋值时,在上面的样式中就会给Image控件和TextBlock赋值。
<local:MyButton Content="系统状态监控" Height="40" Width="132"
Style="{StaticResource sysStatusButton}"
ImgSource="/Test13;component/Images/2.png"
Click="MyButton_Click" />
<local:MyButton Content="设备监控列表"
Height="40"
Width="132"
Margin="5,0,5,0"
Style="{StaticResource sysStatusButton}"
ImgSource="/Test13;component/Images/3.png"
Click="MyButton_Click_1" />