創(chuàng)建
image.png
創(chuàng)建完成后系統(tǒng)會(huì)幫我們自動(dòng)生成一個(gè)文件夾(Themes)和一個(gè)通用文件(Generic)
image.png
和UserControl區(qū)別
- UserControl:利用現(xiàn)有控件進(jìn)行組裝成一個(gè)塊
- CustomControl:模板與行為分離,編輯模板不會(huì)像Winfrom那樣影響行為愁铺,真正的就是一個(gè)控件考传。
使用
-
生成的文件中已告訴了我們?nèi)绾问褂茫覀兙桶凑詹襟E1a來(lái)試一下
image.png -
打開(kāi)系統(tǒng)幫我們生成的Generic.xaml文件,發(fā)現(xiàn)有一些錯(cuò)誤域携,這是因?yàn)槲业淖远x控件是在我自己創(chuàng)建的一個(gè)CustomControls文件夾下導(dǎo)致的巴帮。
image.png -
那我們就按照1a把上面的更換掉,然后重新編譯一下就可以了瞬女,另外我們?cè)跇邮嚼锩婕右粋€(gè)TextBlock來(lái)測(cè)試顯示
image.png - 最后就是我們使用的時(shí)候也和上面一樣窍帝,需要更換一下標(biāo)記文件的根元素
image.png
注意:不要在Generic.xaml文件<TextBlock Text="test customcontrol" FontSize="30"/>里面的Text中寫(xiě)中文測(cè)試,否則會(huì)報(bào)錯(cuò)诽偷,原因還不知道
image.png
使用示例:
- 自定義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
{
// 依賴(lài)屬性 :為了做綁定
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>
-
使用和效果
image.png
復(fù)用
-
當(dāng)我們只需要對(duì)控件進(jìn)行一些外觀(guān)調(diào)整時(shí)坤学,就可以使用編輯模板來(lái)去復(fù)用,而不用更改自定義控件本身报慕。
image.png