WPF Demo20 模板

<Window x:Class="控件模板.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources >
        <ControlTemplate x:Key="buttonTemplate" TargetType="Button" >
                <Ellipse Name="faceEllipse" Height="50" Width="100"  Fill="{TemplateBinding Button.Background}"/>
            <ControlTemplate.Triggers >
                <Trigger Property="Button.IsMouseOver" Value="True">
                    <Setter Property="Button.Background" Value="red"/>
                </Trigger >
            </ControlTemplate.Triggers >
        </ControlTemplate >
    </Window.Resources >
    
    <Grid>
        <Button Content="Button" HorizontalAlignment="Left" Margin="46,38,0,183" Name="button3"  Width="123" Template="{StaticResource buttonTemplate}"/>
        <Ellipse Height="50" HorizontalAlignment="Left" Margin="238,28,0,0" Name="ellipse1"  Stroke="Red" VerticalAlignment="Top" Width="100" />
    </Grid>
</Window>

一、模板分类
FrameworkTemplate==》
ControlTemplate;
ItemsPanelTemplate;
DataTemplate==》ContentPresenter、HierarchicalDataTemplate

其中ControlTemplate和ItemsPanelTemplate是控件模板,DataTemplate是数据模板,
他们都派生自FrameworkTemplate抽象类。

二、ControlTemplate模板
ControlTemplate:控件模板主要有两个重要属性,VisualTree内容属性和Triggers触发器。
所谓VisualTree(视觉树),就是呈现我们所画的控件。
Triggers可以对我们的视觉树上的元素进行一些变化。一般用于单内容控件。

wpf提供了一个ContentPresenter,它的作用就是把原有模板的属性原封不动的投放到自定义模板中。

实例二:

<Window x:Class="模板2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="350" Width="525" >
    <Window.Resources>
        <Style TargetType="Button">
            <!--Set to true to not get any properties from the themes.-->
            <Setter Property="OverridesDefaultStyle" Value="True"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid>
                            <Ellipse x:Name="ellipse1" Fill="AliceBlue" Width="50" Height="50"/>
                            <ContentPresenter HorizontalAlignment="Center"
                              VerticalAlignment="Center" Content="test"/>
                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter TargetName="ellipse1" Property="Fill" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Canvas>
        <Button Canvas.Left="30" Canvas.Top="21" Name="button1" Click="button1_Click" />
    </Canvas>
</Window>
using System.Windows;

namespace 模板2
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, RoutedEventArgs e)
        {
            Window1 w = new Window1();
            w.Show();
        }
    }
}

  

<Window x:Class="模板2.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="Button">
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="Button">
                        <Grid>
                            <Ellipse x:Name="ellipse1" Width="65" Height="65" >
                                <Ellipse.Fill>
                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                        <GradientStop Offset="0" Color="blue"/>
                                        <GradientStop Offset="1" Color="LightBlue"/>
                                    </LinearGradientBrush>
                                </Ellipse.Fill>
                            </Ellipse>
                            <!--
                            显示内容
                            Content="{TemplateBinding Content}" 可写可不写
                            -->
                            <!--<ContentPresenter  HorizontalAlignment="Center" VerticalAlignment="Center" Content="{TemplateBinding Content}"/>-->
                            <ContentPresenter  HorizontalAlignment="Center" VerticalAlignment="Center" />
                            
                            <Ellipse Width="50" Height="50">
                                <Ellipse.Fill>
                                    <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
                                        <GradientStop Offset="0" Color="White"/>
                                        <GradientStop Offset="1" Color="Transparent"/>
                                    </LinearGradientBrush>
                                </Ellipse.Fill>
                            </Ellipse>
                        </Grid>

                        <ControlTemplate.Triggers>
                            <Trigger Property="IsMouseOver" Value="true">
                                <Setter TargetName="ellipse1" Property="Fill" Value="Red"/>
                            </Trigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Setter Property="FontSize" Value="18"/>
            <Setter Property="Foreground" Value="Coral"/>
        </Style>
    </Window.Resources>
    <Grid>
        <Button Content="aa" Margin="-49,0,49,0" />
        <Button Content="bb" Margin="65,0,-65,0" />
    </Grid>
</Window>
<!--ContentControl继承于Control的,用MSDN的话是:
表示包含单项内容的控件、ContentControl 可以包含任何类型的公共语言运行库对象。

为了提高性能,我们可以用一个ControlPresenter来代替ContentControl,效果还是一样,那他们有什么区别呢?
来看下ControlPresenter这个类,它继承于FreameworkElement。
 
ControlPresenter 通常叫做内容占位符。所以我们可以看到

<ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center"/> 来代替
<ContentControl VerticalAlignment="Center" HorizontalAlignment="Center" Content="{TemplateBinding Content}"/> 。
这里少了Content绑定父容器,因为ControlPresenter有个隐式的Content="{TemplateBinding Content}",也就是你可以写也可以不写它。

从他们的基类可以看出,ContentControl比ContentPresenter大多了。
其实ControlPresenter是一个原始的构建块,而ContentControl是一个带控件模板的成熟控件(里面包含ControlPresenter)。
所以我们一般用ControlPresenter。--> 
    

原文地址:https://www.cnblogs.com/YYkun/p/6873583.html