WPF--控件模板
以下视频学习笔记:
https://www.bilibili.com/video/BV1gq4y1D76d?p=20&spm_id_from=pageDriver
前言:
wpf的模板有多种方式,可以分为:
控件模板(ControlTemplate),
控件列表模板(ItemsPanelTemplate),
数据模板(DataTemplate)。
其中ControlTemplate和ItemsPanelTemplate都属于控件模板
模板可以放在控件内部,那么只有这个控件才能使用,为了实现共享模板等,我们可以把模板定义在resource里面,所以我们完全可以把以模板代码添加到window.resource中,方便调用
一,按钮控件示例
效果:

1,控件模板和模板触发器

2,模板是控件的Template 属性,Template 是一个ControlTemplate对象

二,TextBox控件:基于现有默认模板编写
效果:

1,两种方式编辑副本


2,模板代码:
<Style x:Key="UserNameTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"
CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="" FontFamily="../Assets/IconFont/#iconfont" FontSize="20" Foreground="#ddd" VerticalAlignment="Center" HorizontalAlignment="Center"></TextBlock>
<ScrollViewer x:Name="PART_ContentHost" Grid.Column="1" Focusable="false"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
VerticalAlignment="Center" MinHeight="20"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style x:Key="PasswordBoxStyle" TargetType="{x:Type PasswordBox}">
<Setter Property="PasswordChar" Value="●"/>
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type PasswordBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"
CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="" FontFamily="../Assets/IconFont/#iconfont" FontSize="20" Foreground="#ddd" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" Grid.Column="1"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
VerticalAlignment="Center" MinHeight="20"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
<Style x:Key="ValidationCodeTextBoxStyle" TargetType="{x:Type TextBox}">
<Setter Property="Background" Value="{DynamicResource {x:Static SystemColors.WindowBrushKey}}"/>
<Setter Property="BorderBrush" Value="{StaticResource TextBox.Static.Border}"/>
<Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/>
<Setter Property="BorderThickness" Value="1"/>
<Setter Property="KeyboardNavigation.TabNavigation" Value="None"/>
<Setter Property="HorizontalContentAlignment" Value="Left"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="AllowDrop" Value="true"/>
<Setter Property="ScrollViewer.PanningMode" Value="VerticalFirst"/>
<Setter Property="Stylus.IsFlicksEnabled" Value="False"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True"
CornerRadius="5">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"></ColumnDefinition>
<ColumnDefinition Width="188"></ColumnDefinition>
<ColumnDefinition Width="80"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="" FontFamily="../Assets/IconFont/#iconfont" FontSize="20" Foreground="#ddd" HorizontalAlignment="Center" VerticalAlignment="Center"></TextBlock>
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" Grid.Column="1"
HorizontalScrollBarVisibility="Hidden"
VerticalScrollBarVisibility="Hidden"
VerticalAlignment="Center" MinHeight="20"/>
<Image Source="../Assets/Images/验证码.jpg" Grid.Column="2"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsInactiveSelectionHighlightEnabled" Value="true"/>
<Condition Property="IsSelectionActive" Value="false"/>
</MultiTrigger.Conditions>
<Setter Property="SelectionBrush" Value="{DynamicResource {x:Static SystemColors.InactiveSelectionHighlightBrushKey}}"/>
</MultiTrigger>
</Style.Triggers>
</Style>
3,引用目标样式

三,字体图标
1,从 www.iconfont.cn 下载字体图标

2,下载下来的.ttf文件复制到项目资源文件夹中:

3,使用:
<Button Height="40" Width="40" Content="" FontFamily="../Assets/IconFont/#iconfont" FontSize="12" ></Button>

4,注意:如果是新ttf文件替换旧的,如果新增的图标没反应,就重启VS
四,统一样式修改
效果:

代码:

五,字典资源
1,新建一个字典资源

2,引用资源

3,使用资源

4,如果按钮的样式都一样,可以把按钮的大小,字体颜色都写入资源中
优化后的资源代码:

5,设置按钮的代码就更简洁了

六,合并资源

<Window.Resources>
<ResourceDictionary >
<!--合并资源-->
<ResourceDictionary.MergedDictionaries>
<!--这是引入默认的资源-->
<ResourceDictionary Source="../Assets/Styles/DefaultStyle.xaml" ></ResourceDictionary>
<!--这是针对当前RadioButton的资源样式-->
<ResourceDictionary>
<Style TargetType="RadioButton" x:Key="NavButtonStyle">
<Setter Property="Foreground" Value="White"></Setter>
<Setter Property="Template" >
<Setter.Value>
<ControlTemplate TargetType="RadioButton">
<Border Background="Transparent" CornerRadius="8" Name="Back">
<ContentControl Content="{TemplateBinding Content}" VerticalAlignment="Center" HorizontalAlignment="Center" Margin="20,4"></ContentControl>
</Border>
<!--设置选中的时候的状态-->
<ControlTemplate.Triggers>
<Trigger Property="IsChecked" Value="True">
<Setter TargetName="Back" Property="Background" Value="#44ffffff"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Window.Resources>
七:搜索框模板和效果
【7.1】效果

【7.2】TextBox模板
<!--控件模板-->
<ControlTemplate TargetType="{x:Type TextBox}" x:Key="SearchTextBoxTemplate">
<Border x:Name="border" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"
Background="{TemplateBinding Background}" SnapsToDevicePixels="True"
CornerRadius="10">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="30"></ColumnDefinition>
<ColumnDefinition></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="" FontFamily="../Assets/IconFont/#iconfont" VerticalAlignment="Center" HorizontalAlignment="Center"
Foreground="#44ffffff" FontSize="16"></TextBlock>
<!--默认有内容的时候,显示"请输入搜索内容..."-->
<TextBlock Text="请输入搜索内容..." Grid.Column="1" VerticalAlignment="Center" Name="mt" Visibility="Collapsed"></TextBlock>
<ScrollViewer Grid.Column="1" x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"
VerticalAlignment="Center"/>
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Opacity" TargetName="border" Value="0.56"/>
</Trigger>
<Trigger Property="IsMouseOver" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.MouseOver.Border}"/>
</Trigger>
<Trigger Property="IsKeyboardFocused" Value="true">
<Setter Property="BorderBrush" TargetName="border" Value="{StaticResource TextBox.Focus.Border}"/>
</Trigger>
<!--绑定到本身的Text属性上-->
<!--没内容的时候Value="",显示这个mt的属性(显示:"请输入搜索内容..."-->
<DataTrigger Binding="{Binding Text,RelativeSource={RelativeSource Self}}" Value="">
<Setter TargetName="mt" Property="Visibility" Value="Visible"></Setter>
</DataTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
【7.2】TextBox 绑定模板
<!--绑定模板:Template="{StaticResource SearchTextBoxTemplate}-->
<TextBox Grid.Row="1" HorizontalAlignment="Right" VerticalAlignment="Center" Width="300" Height="32" Template="{StaticResource SearchTextBoxTemplate}"
Background="#22000000" Text="{Binding SearchText }" Foreground="White" >
</TextBox>
八,单选框数据绑定
引入命名空间
xmlns:converter="clr-namespace:Zhaoxi.CourseManagement.Converter"
<!--在资源里面定义一下,调用的时候就调用这个genderConverter-->
<converter:GenderConverter x:Key="genderConverter"/>
<!--RadioButton控件模板-->
<ControlTemplate TargetType="RadioButton" x:Key="GenderRadioButtonTemplate">
<Grid>
<!--1个RadioButton有2列-->
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!--默认情况下隐藏Visibility="Collapsed"-->
<Border Width="14" Height="14" CornerRadius="7" BorderThickness="1" BorderBrush="#007dea" VerticalAlignment="Top" Margin="5,0,0,0">
<Border Width="8" Height="8" CornerRadius="4" Background="White" Name="point" Visibility="Collapsed"/>
</Border>
<!--第2列,文字部分-->
<ContentControl Grid.Column="1" Content="{TemplateBinding Content}" Margin="5,0,0,0"></ContentControl>
</Grid>
<ControlTemplate.Triggers>
<!--如果IsChecked,显示Name为point的标签-->
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" Value="Visible" TargetName="point"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
<Grid Grid.Row="1" Margin="20,0">
<!--统一样式设定-->
<Grid.Resources>
<!--所有TextBlock前景色白色,如果没有反应,就把white删除在编辑下就好-->
<Style TargetType="TextBlock">
<Setter Property="Foreground" Value="White"/>
<Setter Property="FontSize" Value="14"/>
</Style>
<!--所有RadioButton前景色白色-->
<Style TargetType="RadioButton">
<Setter Property="Foreground" Value="White"/>
</Style>
</Grid.Resources>
<Grid.RowDefinitions>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal">
<TextBlock Text="用户名:"/>
<TextBlock Text="{Binding UserInfo.UserName}" Margin="10,0,0,0"/>
</StackPanel>
<StackPanel Orientation="Horizontal" Grid.Row="1">
<TextBlock Text="性 别:"/>
<!--调用资源genderConverter-->
<RadioButton Content="男" Margin="10,0,0,0" Template="{StaticResource GenderRadioButtonTemplate}"
IsChecked="{Binding UserInfo.Gender,Converter={StaticResource genderConverter},ConverterParameter=1}" />
<RadioButton Content="女" Margin="10,0,0,0" Template="{StaticResource GenderRadioButtonTemplate}"
IsChecked="{Binding UserInfo.Gender,Converter={StaticResource genderConverter},ConverterParameter=2}"/>
</StackPanel>
</Grid>
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Data;
namespace Zhaoxi.CourseManagement.Converter
{
class GenderConverter : IValueConverter
{
/// <summary>
/// modle向view转换
/// </summary>
/// <param name="value">model的值</param>
/// <param name="targetType"></param>
/// <param name="parameter">前端传入的值</param>
/// <param name="culture"></param>
/// <returns></returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value == null || parameter == null)
{
return false;
}
return value.ToString() == parameter.ToString();
//比如:UserInfo.Gender=1,ConverterParameter=1,范围true
}
/// <summary>
/// view向modle转换,点击RadioButton触发这个事件
/// </summary>
/// <param name="value"></param>
/// <param name="targetType"></param>
/// <param name="parameter"></param>
/// <param name="culture"></param>
/// <returns></returns>
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return parameter;
}
}
}

浙公网安备 33010602011771号