标签:有趣 content 构建 运行 present 元素属性 cep ems 动态
原文:控件模板添加的元素分类称之为逻辑树,可视化树是逻辑树的扩展版本,目的用于将元素分成更小的部分。WPF提供了用于浏览逻辑树和可视化树的两个类:System.Windows.LogicalTreeHelper和System.Windows.Media.VisualTreeHelper。VisualTreeHelper类还提供了一种研究应用程序中可视化树的有趣的方法,使用GetChild()方法,可以遍历任意串口的可视化树。
2.1)、可使用样式改变可视化树的元素。可使用Style.TargetType(很重要,假设不指定类型为Button,那么Button元素应用此模板不会显示内容)属性指定修改的特定元素,甚至当控件属性发生变化时,可使用触 发器自动完成更新。
2.2)、可为控件创建新模板。
先分析一下MainWinow窗口中的元素的逻辑树。
<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">
<StackPanel Margin="5">
<Button Name="btn1" Padding="5" Margin="5" Click="cmd_Click">First Button</Button>
<Button Name="btn2" Padding="5" Margin="5" Click="cmd_Click">Second Button</Button>
</StackPanel>
</Window>
逻辑树:
新建一个名叫VisualTreeDisplay的Windows窗口,在窗口后台写代码。
VisualTreeDisplay窗口的xaml代码:
<Window x:Class="可视化树.VisualTreeDisplay" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" Title="VisualTreeDisplay" Height="300" Width="300">
<TreeView Name="treeElements"></TreeView> </Window>
VisualTreeDisplay窗口的后台代码:
public partial class VisualTreeDisplay : Window
{
public VisualTreeDisplay()
{
InitializeComponent();
}
public void ShowVisualTree(DependencyObject element)
{
//先清除集合中的项。
treeElements.Items.Clear();
ProcessElement(element, null);
}
private void ProcessElement(DependencyObject element, TreeViewItem previousItem)
{
//创建视图树。
TreeViewItem item = new TreeViewItem();
//获取依赖元素标题。
item.Header = element.GetType().Name;
//打开折叠。
item.IsExpanded = true;
if (previousItem == null)
{
treeElements.Items.Add(item);
}
else
{
previousItem.Items.Add(item);
}
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(element); i++)
{
ProcessElement(VisualTreeHelper.GetChild(element, i), item);
}
}
}
在MainWindow中xaml代码:
<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">
<StackPanel Margin="5">
<Button Padding="5" Margin="5" Click="cmd_Click">First Button</Button>
<Button Padding="5" Margin="5" Click="cmd_Click">Second Button</Button>
</StackPanel>
</Window>
MainWindow后台代码:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void cmd_Click(object sender, RoutedEventArgs e)
{
//查看窗口的可视化状态:
//VisualTreeDisplay vtd = new VisualTreeDisplay();
//vtd.ShowVisualTree((this));
//vtd.Show();
//查看Button的可视化状态。
VisualTreeDisplay vtd = new VisualTreeDisplay();
vtd.ShowVisualTree((FrameworkElement)sender);
vtd.Show();
}
}
查看窗口的可视化状态(参数传的this),会显示出可视化逻辑状态窗口:
查看button的可视化逻辑窗口(里面有Border元素(用于修饰)和ContentPresenter元素(显示内容)):
在<StackPanel> 元素中再添加一个Image元素,命名为img1,接下来看看图片的可视化状态,说明(就显示个Image,说明没有可视化逻辑显示,不能应用模板):
private void img1_MouseDown(object sender, MouseButtonEventArgs e)
{
VisualTreeDisplay vtd = new VisualTreeDisplay();
vtd.ShowVisualTree((FrameworkElement)sender);
vtd.Show();
}
在上面的Window窗口中,可视化树包含了一个Border元素,这个Border元素又包含了一个AdornerSecorator元素(用于修饰),AdornerDecorator元素内是一个ContentPresenter元素(该元素承载了窗口内容),窗口内包含了一的StackPanel面板具有两个Button控件,每个Button控件包含了一个ButtonChrome元素(该元素绘制按钮的标准可视化外观)和一个ContentPresenter元素(该元素包含了元素的内容),每个按钮额ContentPresenter元素是一个TextBlock元素,TextBlock元素封装了在窗口中可见的文本。
模板主要用于修改元素外观,但不能修改其行为。模板一般分为三种模板,分别是:控件模板(ControlTemplate)、数据模板(DataTemplate)和面板模板(ItemPanelTemplate),这些模板都继承自FrameworkTemplate基类。控件模板提供了在可视化树种看到的扩展内容,ButtonChorme类定义按钮的标准可视化外观,而ContentPresenter类存储了提供的所有内容。其中,ButtonChorme类继承自Decorator类(与Border类非常类似),这意味着这些类是为了在其他元素周围添加图形装饰而设计的。
为Button设置模板。
xaml代码:
<Window.Resources>
<!--在资源中定义一个名叫button_template的模板-->
<ControlTemplate x:Key="button_template" TargetType="{x:Type Button}>
<!--添加Border元素,为其设置属性-->
<Border BorderBrush="Orange" Background="LightCyan" TextBlock.Foreground="Black" BorderThickness="2" CornerRadius="5">
<ContentPresenter RecognizesAccessKey=‘True‘ HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
</Border>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<!--为第一个Button元素设置模板。-->
<Button Template="{StaticResource button_template}" Padding="5" Margin="5" Height="50">我是Button1</Button>
<Button Padding="5" Margin="5" Height="50">我是Button2</Button>
</StackPanel>
效果图:
在上面的控件模板中,设置了TargetType属性,以明确指示该模板是为按钮设计的,与样式类似,这总是一个可以遵循的好约定,在内容控件(如Button)中也需要使用该约定。否则ContentPresenter元素就不能工作。从技术角度看,ContentPresenter之所以能工作,是因为它有一个模板绑定,用于将ContentPresenter.Content属性设置为Button.Content属性,然而该绑定是隐式的。
<StackPanel>
<!--为第一个Button元素设置模板。-->
<Button Template="{StaticResource button_template}" Padding="5" Margin="10">我是Button1</Button>
<Button Padding="5" Margin="5" Height="50">我是Button2</Button>
</StackPanel>
在该例中存在一个问题,现在为按钮添加的Margin属性指定为10,并将padding属性的值设置为5,Stackpanel控件关注的是按钮的Margin属性,却忽略了Padding属性,使按钮的内容和侧边挤压在一起,此处额问题是Padding属性不起作用,除非在模板中特别注意它,幸运的是WPF专门针对该目的设计了一个工具,模板绑定。通过使用模板绑定,模板可从应用模板的控件中提取一个值,就是为ContentPresenter元素中的Margin属性通过模板绑定到Paddding属性中。
<!--通过模板绑定到Padding属性上-->
<ContentPresenter Margin="{TemplateBinding Padding}" RecognizesAccessKey=‘True‘ HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
<StackPanel>
<!--为Button元素设置模板。这样Padding属性就其作用了(如果为button设置了Height属性,将看不到效果,切记!)-->
<Button Template="{StaticResource button_template}" Padding="20" Margin="10" >我是Button1</Button>
</StackPanel>
根据之前的为Button设置简单模板绑定,虽然可以改变元素的外观,但把鼠标放到元素上,或者点击图片时没有什么反应,这个时候使用属性触发器的IsMouseOver和IsPressed属性来解决这个问题。其中,IsMouseOver是鼠标滑到元素上的效果,IsPressed是点击图片的效果。设置效果的时候,可通过TargetName指定要修改的具体元素的属性。
<Window.Resources>
<!--在资源中定义一个名叫button_template的模板-->
<ControlTemplate x:Key="button_template" TargetType="{x:Type Button}">
<!--添加Border元素,为其设置属性-->
<Border Name="Border" BorderBrush="Orange" Background="LightCyan" TextBlock.Foreground="Black" BorderThickness="2" CornerRadius="5">
<ContentPresenter Margin="{TemplateBinding Padding}" RecognizesAccessKey=‘True‘ HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
</Border>
<!--设置属性触发器-->
<ControlTemplate.Triggers>
<!--设置一个鼠标移动到元素上的效果(用IsMouseOver属性)-->
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="DarkRed"></Setter>
<Setter TargetName="Border" Property="BorderBrush" Value="Red"></Setter>
</Trigger>
<!--设置一个点击元素的效果(用IsPressed属性)-->
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="Yellow"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<!--为第一个Button元素设置模板。-->
<Button Template="{StaticResource button_template}" Padding="20" Margin="10" >我是Button1</Button>
<Button Padding="5" Margin="5" Height="50">我是Button2</Button>
</StackPanel>
在以上案例中,如果存在多个按钮,如果点击了其中的一个按钮,不能明确地看出此按钮是否获取了焦点,但是可以很容易地添加另一个元素以显示是否具有焦点,并且可以简单地使用触发器根据Button.IsKeyBoardFocused属性隐藏显示该属性。
实现思路是:在Border元素中添加一个Grid元素,在Grid元素中添加一个Rectangle元素(默认是隐藏),然后再添加一个Contentpresenter元素。当点击图片的时候,触发Button元素的IsKeyboardFocused属性,然后将Rectangle显示出来。
<Window.Resources>
<!--在资源中定义一个名叫button_template的模板-->
<ControlTemplate x:Key="button_template" TargetType="{x:Type Button}">
<Border Name="Border" BorderBrush="Orange" Background="LightCyan" TextBlock.Foreground="Black" BorderThickness="2" CornerRadius="5">
<!--添加Border元素,为其设置属性-->
<Grid>
<!--添加矩形元素,将矩形设置成点划线,默认是隐藏-->
<Rectangle Name="FocusRectangle" Visibility="Hidden" Stroke="Black" StrokeThickness="1" StrokeDashArray="1,2" SnapsToDevicePixels="True"></Rectangle>
<!--为Grid中添加ContentPresenter元素-->
<ContentPresenter Margin="{TemplateBinding Padding}" RecognizesAccessKey=‘True‘ HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
</Grid>
</Border>
<!--设置属性触发器-->
<ControlTemplate.Triggers>
<!--设置一个鼠标移动到元素上的效果(用IsMouseOver属性)-->
<Trigger Property="IsMouseOver" Value="true">
<Setter TargetName="Border" Property="Background" Value="DarkRed"></Setter>
<Setter TargetName="Border" Property="BorderBrush" Value="Red"></Setter>
</Trigger>
<!--设置一个点击元素的效果(用IsPressed属性)-->
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="Yellow"></Setter>
</Trigger>
<!--设置IsKeyboardFocused属性,将举行显示出来。-->
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="FocusRectangle" Property="Visibility" Value="Visible"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<!--为第一个Button元素设置模板。-->
<Button Template="{StaticResource button_template}" Padding="20" Margin="10" >我是Button1</Button>
<Button Template="{StaticResource button_template}" Padding="20" Margin="10" >我是Button2</Button>
<Button Padding="5" Margin="5" Height="50">我是Button2</Button>
</StackPanel>
效果图:当点击了第二个图片时,出现虚线。
就是当按钮的IsEnabled=false的时候,设置背景色。这个时候需要设置IsEnabled属性触发器了。
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="TextBlock.Foreground" Value="gray"></Setter>
<Setter TargetName="Border" Property="Background" Value="MistyRose"></Setter>
</Trigger>
</ControlTemplate.Triggers>
<Button Template="{StaticResource button_template}" IsEnabled="False" Padding="5" Margin="10" Height="50">我是Button3</Button>
模板和样式有类似之处,样式和模板都可以改变元素的外观。然而,样式被限制在一个小得多的范围之内。一般情况下,模板用于更改元素的外观,样式用于更改元素属性。
通过EventTrigger设置事件触发器,通过RoutedEvent指定事件。一般事件处理器用于处理动画。
<Window.Resources>
<!--定义一个控件模板-->
<ControlTemplate x:Key="button_template" TargetType="{x:Type Button}">
<!--添加Border元素-->
<Border Name="Border" CornerRadius="5" BorderBrush="Orange" BorderThickness="3" Background="Azure">
<!--添加Grid元素-->
<Grid>
<Rectangle SnapsToDevicePixels="True" Visibility="Hidden" StrokeDashArray="1,2" StrokeThickness="1"></Rectangle>
<ContentPresenter Margin="{TemplateBinding Padding}" HorizontalAlignment="Center" VerticalAlignment="Center"></ContentPresenter>
</Grid>
</Border>
<!--定义触发器-->
<ControlTemplate.Triggers>
<!--定义一个事件触发器(鼠标移动到元素上),改变Border元素的背景色-->
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color">
<ColorAnimation Duration="0:0:0:1" To="Blue">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<!--定义一个事件触发器(鼠标离开元素时发生),将Border元素的背景色改变成原来的背景色-->
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard Storyboard.TargetName="Border" Storyboard.TargetProperty="Background.Color">
<ColorAnimation Duration="0:0:0:0" To="Azure">
</ColorAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<!--为图片应用模板-->
<Button Template="{StaticResource button_template}" Padding="30" Margin="10" Width="150">我是Button1</Button>
<Button Template="{StaticResource button_template}" Padding="30" Margin="10" Width="150">我是Button2</Button>
<Button Template="{StaticResource button_template}" Padding="30" Margin="10" Width="150">我是Button3</Button>
</StackPanel>
当使用控件模板时,需要决定如何更广泛地共享模板,以及是否希望自动地或明确地应用模板,但是要思考一个问题,将他们限定在特定的窗口中吗?大多数情况下,控件模板应用于多个窗口,甚至可能应用于整个应用程序中,为避免多次定义模板,基本上都是定义在资源字典中,然后将他们合并到Application.Resource中,每个控件模板创建单独的资源字典,而不要把所有的模板都定义在同一个资源字典中。
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<!--定义一个名叫HighlightBackground的画刷,用于设置鼠标移动到元素上触发的的IsMouseOver属性,更改Border背景色-->
<RadialGradientBrush x:Key="HighlightBackground" RadiusX="1" RadiusY="5" GradientOrigin="0.5,0.3">
<GradientStop Offset="0" Color="White"></GradientStop>
<GradientStop Offset=".4" Color="Blue"></GradientStop>
</RadialGradientBrush>
<!--定义一个名叫HighlightBackground的画刷,用于设置鼠标点击button时,触发的IsPressed属性,更改Border背景色。-->
<RadialGradientBrush x:Key="PressedBackground" RadiusX="1" RadiusY="5" GradientOrigin="0.5,0.3">
<GradientStop Offset="0" Color="White"></GradientStop>
<GradientStop Offset="1" Color="Blue"></GradientStop>
</RadialGradientBrush>
<!--定义一个画刷,目的用于设置Button按钮的背景色-->
<SolidColorBrush x:Key="DefaultBackground" Color="Blue"></SolidColorBrush>
<!--定义一个画刷,用于设置禁用按钮的背景色-->
<SolidColorBrush x:Key="DisabledBackground" Color="Gray"></SolidColorBrush>
<!--定义一个画刷,用于设置模板中的Border元素的颜色。-->
<RadialGradientBrush x:Key="Border" RadiusX="1" RadiusY="5" GradientOrigin="0.5,0.3">
<GradientStop Offset="0" Color="White"></GradientStop>
<GradientStop Offset="1" Color="Blue"></GradientStop>
</RadialGradientBrush>
<!--定义一个名叫ContentPresenter_Style的样式,用于更改模板中的样式,将字体颜色变成白色。-->
<Style x:Key="ContentPresenter_Style">
<Setter Property="Control.Foreground" Value="White"></Setter>
</Style>
<!--定义个模板-->
<ControlTemplate x:Key="GradientTemplate" TargetType="{x:Type Button}">
<Border Name="Border" BorderBrush="{StaticResource ResourceKey=Border}" BorderThickness="2" CornerRadius="2" Background="{StaticResource ResourceKey=DefaultBackground}">
<Grid>
<Rectangle Name="FocusRectangle" Visibility="Hidden" Stroke="Black" StrokeThickness="1" StrokeDashArray="1,2" SnapsToDevicePixels="True"></Rectangle>
<ContentPresenter Name="cp" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"></ContentPresenter>
</Grid>
</Border>
<!--定义模板触发器-->
<ControlTemplate.Triggers>
<!--定义属性触发器(鼠标移动到元素上)-->
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource ResourceKey=HighlightBackground}"></Setter>
<Setter TargetName="cp" Property="Style" Value="{StaticResource ResourceKey= ContentPresenter_Style}"></Setter>
</Trigger>
<!--定义属性触发器(点击元素时触发)-->
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource ResourceKey=PressedBackground}"></Setter>
</Trigger>
<!--定义属性触发器(获取焦点)-->
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="FocusRectangle" Property="Visibility" Value="Visible"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="{StaticResource ResourceKey=DisabledBackground}"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</ResourceDictionary>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ButtonDictionary.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
<StackPanel> <Button Template="{StaticResource GradientTemplate}" Padding="30" Margin="10" Width="150">我是Button1</Button> <Button Template="{StaticResource GradientTemplate}" Padding="30" Margin="10" Width="150">我是Button2</Button> <Button Template="{StaticResource GradientTemplate}" IsEnabled="False" Padding="30" Margin="10" Width="150">我是Button3</Button> </StackPanel>
效果图:
就是在ButtonDictionary.xaml文件中添加一个style样式,为样式设置模板属性,然后值指向定义的模板,然后在窗口中设置元素的style属性指向ButtonDictionary.xaml文件中定义的样式即可。
<!--添加名叫Button_Style的样式,设置Template属性,值指向定义的模板-->
<Style x:Name="Button_Style" TargetType="{x:Type Button}">
<Setter Property="Template" Value="{StaticResource ResourceKey=GradientTemplate}"></Setter>
</Style>
<StackPanel>
<!--在这个地方是为元素设置样式,而不是通过模板哦--->
<Button Style="{StaticResource Button_Style}" Padding="30" Margin="10" Width="150">我是Button1</Button>
<Button Padding="30" Margin="10" Width="150">我是Button2</Button>
<Button Style="{StaticResource Button_Style}" IsEnabled="False" Padding="30" Margin="10" Width="150">我是Button3</Button>
</StackPanel>
效果图:
也是在ButtonDictionary.xaml中添加一个Style样式,然后为其设置TargetType属性,不要为其指定x:key特性即可。应用模板不可以自动应用到元素上了。
<!--添加Style样式,设置模板属性,值等于上面定义的模板。不用为其指定x:key特性就会自动应用到Button元素上了-->
<Style TargetType="{x:Type Button}">
<Setter Property="Control.Template" Value="{StaticResource GradientTemplate}"></Setter>
</Style>
窗口中不用引用,就会自动应用了:
<StackPanel>
<Button Padding="30" Margin="10" Width="150">我是Button1</Button>
<Button Padding="30" Margin="10" Width="150">我是Button2</Button>
<Button IsEnabled="False" Padding="30" Margin="10" Width="150">我是Button3</Button>
</StackPanel>
效果图:
在一些应用程序中,可能希望动态地改变模板,比如通常所说的皮肤。基本技巧是运行时加载新的资源字典,并使用新加载的资源字典替代当前的资源字典(不需要替换所有资源,只需要替换那些用于皮肤的资源)。主要用于检索ResourceDictionary对象,该对象经过编译并作为资源嵌入到应用程序中。
嵌套的模板:
xaml代码:
<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>
<!--定义一个名叫HighlightBackground的画刷,用于设置鼠标移动到元素上触发的的IsMouseOver属性,更改Border背景色-->
<RadialGradientBrush x:Key="HighlightBackground" RadiusX="1" RadiusY="5" GradientOrigin="0.5,0.3">
<GradientStop Offset="0" Color="White"></GradientStop>
<GradientStop Offset=".4" Color="Blue"></GradientStop>
</RadialGradientBrush>
<!--定义一个名叫HighlightBackground的画刷,用于设置鼠标点击button时,触发的IsPressed属性,更改Border背景色。-->
<RadialGradientBrush x:Key="PressedBackground" RadiusX="1" RadiusY="5" GradientOrigin="0.5,0.3">
<GradientStop Offset="0" Color="White"></GradientStop>
<GradientStop Offset="1" Color="Blue"></GradientStop>
</RadialGradientBrush>
<!--定义一个画刷,目的用于设置Button按钮的背景色-->
<SolidColorBrush x:Key="DefaultBackground" Color="Blue"></SolidColorBrush>
<!--定义一个画刷,用于设置禁用按钮的背景色-->
<SolidColorBrush x:Key="DisabledBackground" Color="Gray"></SolidColorBrush>
<!--定义一个画刷,用于设置模板中的Border元素的颜色。-->
<RadialGradientBrush x:Key="Border" RadiusX="1" RadiusY="5" GradientOrigin="0.5,0.3">
<GradientStop Offset="0" Color="White"></GradientStop>
<GradientStop Offset="1" Color="Blue"></GradientStop>
</RadialGradientBrush>
<!--定义一个名叫ContentPresenter_Style的样式,用于更改模板中的样式,将字体颜色变成白色。-->
<Style x:Key="ContentPresenter_Style">
<Setter Property="Control.Foreground" Value="White"></Setter>
</Style>
</Window.Resources>
<StackPanel>
<Button Content="Hello,World" Height="80" Margin="10">
<Button.Style>
<Style>
<Setter Property="Button.Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Name="Border" BorderBrush="{StaticResource ResourceKey=Border}" BorderThickness="2" CornerRadius="2" Background="{StaticResource ResourceKey=DefaultBackground}">
<Grid>
<Rectangle Name="FocusRectangle" Visibility="Hidden" Stroke="Black" StrokeThickness="1" StrokeDashArray="1,2" SnapsToDevicePixels="True"></Rectangle>
<ContentPresenter Name="cp" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True"></ContentPresenter>
</Grid>
</Border>
<ControlTemplate.Triggers>
<!--定义属性触发器(鼠标移动到元素上)-->
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource ResourceKey=HighlightBackground}"></Setter>
<Setter TargetName="cp" Property="Style" Value="{StaticResource ResourceKey= ContentPresenter_Style}"></Setter>
</Trigger>
<!--定义属性触发器(点击元素时触发)-->
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="{StaticResource ResourceKey=PressedBackground}"></Setter>
</Trigger>
<!--定义属性触发器(获取焦点)-->
<Trigger Property="IsKeyboardFocused" Value="True">
<Setter TargetName="FocusRectangle" Property="Visibility" Value="Visible"></Setter>
<Setter TargetName="Border" Property="Background" Value="Yellow"></Setter>
</Trigger>
<Trigger Property="IsEnabled" Value="false">
<Setter TargetName="Border" Property="Background" Value="{StaticResource ResourceKey=DisabledBackground}"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
</StackPanel>
</Window>
效果图:
xaml代码:
<Border BorderBrush="Red" BorderThickness="2" Margin="10" Width="202" Height="202" CornerRadius="5">
<Grid Width="200" Height="200" Margin="-1,-1,0,0">
<Border Name="myBorder" CornerRadius="5" Background="White"/>
<Image Source="1.jpg" Margin="1" Stretch="Fill">
<Image.OpacityMask>
<VisualBrush Visual="{Binding ElementName=myBorder}"/>
</Image.OpacityMask>
</Image>
</Grid>
</Border>
效果图:
End。
标签:有趣 content 构建 运行 present 元素属性 cep ems 动态
原文地址:https://www.cnblogs.com/lonelyxmas/p/9479031.html