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="&#xe61b;" 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;
        }
    }
}

  

 

posted @ 2021-11-14 23:14  包子789654  阅读(355)  评论(0编辑  收藏  举报