创建
创建完成后系统会帮我们自动生成一个文件夹(Themes)和一个通用文件(Generic)
和UserControl区别
- UserControl:利用现有控件进行组装成一个块
- CustomControl:模板与行为分离,编辑模板不会像Winfrom那样影响行为,真正的就是一个控件。
使用
-
生成的文件中已告诉了我们如何使用,我们就按照步骤1a来试一下
-
打开系统帮我们生成的Generic.xaml文件,发现有一些错误,这是因为我的自定义控件是在我自己创建的一个CustomControls文件夹下导致的。
-
那我们就按照1a把上面的更换掉,然后重新编译一下就可以了,另外我们在样式里面加一个TextBlock来测试显示
- 最后就是我们使用的时候也和上面一样,需要更换一下标记文件的根元素
注意:不要在Generic.xaml文件<TextBlock Text="test customcontrol" FontSize="30"/>里面的Text中写中文测试,否则会报错,原因还不知道
使用示例:
- 自定义NumericBox 控件
// 提示作用
[TemplatePart(Name = "PART_Value", Type = typeof(TextBox))]
[TemplatePart(Name = "PART_IncreaseButton", Type = typeof(RepeatButton))]
[TemplatePart(Name = "PART_DncreaseButton", Type = typeof(RepeatButton))]
public class NumericBox : Control
{
// 依赖属性 :为了做绑定
public int Value
{
get { return (int)GetValue(ValueProperty); }
set { SetValue(ValueProperty, value); }
}
public static readonly DependencyProperty ValueProperty =
DependencyProperty.Register("Value", typeof(int), typeof(NumericBox), new PropertyMetadata(0));
static NumericBox()
{
// 重新定义样式文件
// 从哪里找:Themes/Generic.xaml
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericBox), new FrameworkPropertyMetadata(typeof(NumericBox)));
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
var btnIncrease = base.GetTemplateChild("PART_IncreaseButton") as RepeatButton;
var btnDecrease = base.GetTemplateChild("PART_DncreaseButton") as RepeatButton;
var txtValue = base.GetTemplateChild("PART_Value") as TextBox;
if (txtValue != null)
{
Binding binding = new Binding("Value");
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
binding.RelativeSource = new RelativeSource() { AncestorType = typeof(NumericBox), Mode = RelativeSourceMode.FindAncestor };
txtValue.SetBinding(TextBox.TextProperty, binding);
}
if (btnIncrease != null)
{
btnIncrease.Click += BtnIncrease_Click;
}
if (btnDecrease != null)
{
btnDecrease.Click += BtnDecrease_Click;
}
}
private void BtnDecrease_Click(object sender, RoutedEventArgs e)
{
this.Value--;
}
private void BtnIncrease_Click(object sender, RoutedEventArgs e)
{
this.Value++;
}
}
- Generic.xaml添加模板样式
<Style TargetType="{x:Type local:NumericBox}">
<Setter Property="BorderBrush" Value="#DDD"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:NumericBox}">
<Border Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="30"/>
</Grid.ColumnDefinitions>
<TextBox x:Name="PART_Value" VerticalAlignment="Center" Margin="3,5" BorderThickness="0" Foreground="{TemplateBinding Foreground}"/>
<UniformGrid Rows="2" Grid.Column="1">
<RepeatButton Content="+" Name="PART_IncreaseButton" Background="Transparent" BorderThickness="1,0,0,0"/>
<RepeatButton Content="-" Name="PART_DncreaseButton" Background="Transparent" BorderThickness="1,0,0,0"/>
</UniformGrid>
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
-
使用和效果
复用
-
当我们只需要对控件进行一些外观调整时,就可以使用编辑模板来去复用,而不用更改自定义控件本身。