控件模板基礎
需求
需求:客戶對目前的控件樣式不滿意,需要修改樣式。
每一個控件都有Template屬性,可以定制樣式。
我下面以Button為例子:
<Button Content="Button" Height="30" Width="100"><Button.Template><ControlTemplate><Border BorderBrush="Orange" BorderThickness="2" CornerRadius="10"><TextBlock Text="Button" HorizontalAlignment="Center" VerticalAlignment="Center"/></Border></ControlTemplate></Button.Template>
</Button>
這里了利用模版修改了圓角,直接操作Button屬性是沒有的
當把Template單獨拎出來的時候,需要指定TargetType屬性,確實目標控件,和Key屬性,方便調用
屬性傳值
利用TemplateBinding 來綁定控件中的值,如果不寫TemplateBinding,只寫值的話,控件中設置則是沒有效果的。
<ControlTemplate x:Key="btnDemoTemplate" TargetType="Button"><Border BorderBrush="Orange" BorderThickness="2" Background="{TemplateBinding Background}" CornerRadius="10"><TextBlock Text="Button" HorizontalAlignment="Center" VerticalAlignment="Center"/></Border>
</ControlTemplate>
TemplateBinding 綁定使用的屬性 默認的屬性
ControlTemplate:需要指定:TargetType 否則綁定會出現問題 不存在
如果是復雜類型,需要使用ContentPresenter 占位
屬性傳遞:用一個無關大雅的屬性可以給ControlTemplate 傳值
樣式包含模板 但是不必須
引入ContentPresenter
如果Content是復雜類型,則不可以使用TextBlock,需要使用ContentPresenter來占位,進行顯示。
<ControlTemplate x:Key="btnDemoTemplate" TargetType="Button"><Border BorderBrush="Orange" BorderThickness="2" Background="{TemplateBinding Background}" CornerRadius="10"><ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/></Border>
</ControlTemplate>
Style 和 Template
如果樣式中有觸發器,模版中也有觸發器,優先使用模板的觸發器。
<ControlTemplate x:Key="btnDemoTemplate" TargetType="Button"><Border BorderBrush="Orange" BorderThickness="2" Background="{TemplateBinding Background}" CornerRadius="10"x:Name="border"><ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="border" Property="Background" Value="Green"/></Trigger></ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="Button"><Setter Property="Template" Value="{StaticResource btnDemoTemplate}" /><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="Black"/></Trigger></Style.Triggers>
</Style>
我鼠標放上的時候,顏色只會變綠色,不會觸發Style中的觸發器。
擴展:
如果說,我們想要按鈕上有兩個部分顯示,一個是Content,另外一個要字體圖標,請問怎么實現?
利用無關緊要的屬性,進行值傳遞 例如:Tag
<ControlTemplate x:Key="btnDemoTemplate" TargetType="Button"><Border BorderBrush="Orange" BorderThickness="2" Background="{TemplateBinding Background}" CornerRadius="10"x:Name="border"><Grid><Grid.ColumnDefinitions><ColumnDefinition Width="30" /><ColumnDefinition /></Grid.ColumnDefinitions><TextBlock Text="{TemplateBinding Tag}" /><ContentPresenter Grid.Column="1" HorizontalAlignment="Center" VerticalAlignment="Center"/></Grid></Border><ControlTemplate.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter TargetName="border" Property="Background" Value="Green"/></Trigger></ControlTemplate.Triggers>
</ControlTemplate>
<Style TargetType="Button"><Setter Property="Template" Value="{StaticResource btnDemoTemplate}" /><Style.Triggers><Trigger Property="IsMouseOver" Value="True"><Setter Property="Background" Value="Black"/></Trigger></Style.Triggers>
</Style>
<!--加入A就是想要的圖標-->
<Button Height="30" Background="Red" Tag="A" Width="100" Template="{StaticResource btnDemoTemplate}"><Button.Content><Button Content="CeShi" /></Button.Content>
</Button>
效果如下:
注意:TextBlock 和 Border 都是最基礎的控件,基于DrawingRect 和 DrawingContext 繪制,不可以模板開發