模板
ControlTemplate是算法内容的表现形式,决定一个空间长什么样子。
DataTemplate是数据内容的表现形式,决定一个数据显示成什么样子。
ControlTemplate是控件的外衣,DataTemplate是数据的外衣。
DataTemplate常用的地方:
- ContentControl的ContentTemplate属性。
- ItemControl的ItemTemplate属性。
- GridViewColumn的CellTemplate属性。
范例:
<UserControl ContentTemplate="{StaticResource myResourceKey0}"/>
<ListBox ItemTemplate="{StaticResource MyResourceKey1}"
编辑模板
修改
<Window
x:Class="ResourcesDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ResourcesDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prop="clr-namespace:ResourcesDemo.Properties"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow"
Width="400"
Height="250"
mc:Ignorable="d">
<Window.Resources>
<Style x:Key="TextBoxStyle1" TargetType="{x:Type TextBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TextBox}">
<Border x:Name="border" CornerRadius="5" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" SnapsToDevicePixels="True">
<ScrollViewer x:Name="PART_ContentHost" Focusable="false" HorizontalScrollBarVisibility="Hidden" VerticalScrollBarVisibility="Hidden"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<StackPanel x:Name="spl1" >
<TextBox Text="TextBox" Style="{DynamicResource TextBoxStyle1}" Width="150"/>
</StackPanel>
</Window>
PanelTemplate
<Window
x:Class="ResourcesDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:ResourcesDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:prop="clr-namespace:ResourcesDemo.Properties"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow"
Width="400"
Height="250"
mc:Ignorable="d">
<StackPanel x:Name="spl1" >
<ListBox >
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
<Button Content="Button1"/>
<Button Content="Button2"/>
<Button Content="Button3"/>
<Button Content="Button4"/>
</ListBox>
</StackPanel>
</Window>
DataTemplate 与 ControlTemplate
Control.Template
定义 Control 外观的模板。
public System.Windows.Controls.ControlTemplate Template { get; set; }
<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 Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
ContentControl.ContentTemplate
[System.ComponentModel.Bindable(true)]
public System.Windows.DataTemplate ContentTemplate { get; set; }
DataTemplate的载体一般落在ContentPresenter上。ContentPresenter只有ContentTemplate属性。
ContentPresenter标记将Button的Content 在Grid 内垂直和水平居中显示。
<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 Fill="{TemplateBinding Background}"/>
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
FrameworkElement.TemplatedParent
public System.Windows.DependencyObject TemplatedParent { get; }
获取对此元素的模板父级的引用。
FrameworkTemplat
名称 | 备注 | 权限 |
---|---|---|
HasContent | 获取一个值,该值指示此模板是否具有优化内容。 | get; |
IsSealed | 获取一个值,该值指示此对象是否处于不可变状态,如果处于该状态则无法更改对象。 | get; |
Resources | 获取或设置可在此模板范围内使用的资源集合。 | get; set; |
Template | 获取或设置一个引用,该引用指向当编写器定义或应用模板时用于录制或播放模板的 XAML 节点的对象。 | get; set; |
VisualTree | 获取或设置模板的根节点。 | get; set; |
锁定模板,使其无法更改。
名称 | 备注 | 权限 |
---|---|---|
FindName | 查找与此模板中定义的指定名称关联的元素。 | public |
LoadContent | 将模板的内容加载为对象的实例,并返回该内容的根元素。 | public |
RegisterName | 将新的名称/对象对注册到当前名称范围内。 | public |
Seal | 锁定模板,使其无法更改。 | public |
ShouldSerializeResources | 返回一个值,该值指示序列化过程是否应序列化此类的实例上的 Resources 属性值。 | public |
ShouldSerializeVisualTree | 返回一个值,该值指示序列化过程是否应序列化此类的实例上的 VisualTree 属性值。 | public |
UnregisterName | 从 XAML 名称范围中移除名称/对象映射。 | public |
ValidateTemplatedParent | 当在派生类中重写时,为要应用此模板的元素提供规则。 | protected |
名称 | 备注 | 方法 |
---|---|---|
INameScope.FindName | 返回具有提供的标识名称的对象。 | object INameScope.FindName (string name); |
IQueryAmbient.IsAmbientPropertyAvailable | 查询当前范围中是否有指定的环境属性。 | bool IQueryAmbient.IsAmbientPropertyAvailable (string propertyName); |
ControlTemplate
Object->DispatcherObject->FrameworkTemplate->ControlTemplate
名称 | 备注 | 权限 |
---|---|---|
TargetType | 获取或设置此 ControlTemplate 所针对的类型。 | get; set; |
Triggers | 获取根据指定条件应用属性更改或执行操作的 TriggerBase 对象的集合。 | get; |
名称 | 备注 | 权限 |
---|---|---|
ValidateTemplatedParent | 根据一组规则检查模板化父级。 | protected |
DataTemplate
Object->DispatcherObject->FrameworkTemplate->DataTemplate
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=TaskName}" />
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Priority}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
名称 | 备注 | 权限 |
---|---|---|
DataTemplateKey | 获取 DataTemplate 的默认键。 | get; |
DataType | 获取或设置此 DataTemplate 所针对的类型。 | get; set; |
Triggers | 获取触发器的集合,这些触发器根据一个或多个条件应用属性值或执行操作。 | get; |
名称 | 备注 | 权限 |
---|---|---|
ValidateTemplatedParent | 根据一组规则检查模板化父级。 | protected |
Style
名称 | 备注 | 权限 |
---|---|---|
BasedOn | 获取或设置一个作为当前样式的基准的已定义样式。 | get; set; |
IsSealed | 获取一个值,该值指示样式是否为只读(无法更改)。 | get; |
Resources | 获取或设置可在此样式的范围内使用的资源的集合。 | get; set; |
Setters | 获取 Setter 和 EventSetter 对象的集合。 | get; |
TargetType | 获取或设置此样式所针对的类型。 | get; set; |
Triggers | 获取基于指定条件应用属性值的 TriggerBase 对象的集合。 | get; |
名称 | 备注 | 权限 |
---|---|---|
GetHashCode | 返回此 Style 的哈希代码。 | public |
RegisterName | 在当前名称领域内注册一个新的名称-对象对。 | public |
Seal | 锁定此样式和所有工厂与触发器,使得它们无法被更改。 | public |
UnregisterName | 从名称领域内移除名称-对象映射。 | public |
名称 | 备注 | 方法 |
---|---|---|
IAddChild.AddChild | 添加子对象。 | void IAddChild.AddChild (object value); |
IAddChild.AddText | 将节点的文本内容添加到对象。 | void IAddChild.AddText (string text); |
INameScope.FindName | 返回具有提供的标识名称的对象。 | object INameScope.FindName (string name); |
IQueryAmbient.IsAmbientPropertyAvailable | 查询当前范围中是否有指定的环境属性。 | bool IQueryAmbient.IsAmbientPropertyAvailable (string propertyName); |
Style中的Trigger
TriggerBase
名称 | 备注 | 权限 |
---|---|---|
EnterActions | 获取要在触发器对象变为活动状态时应用的 TriggerAction 对象的集合。 此属性不适用于 EventTrigger 类。 | public |
ExitActions | 获取要在触发器对象变为非活动状态时应用的 TriggerAction 对象的集合。 此属性不适用于 EventTrigger 类。 | public |
-
基本Trigger
Object->DispatcherObject->DependencyObject->TriggerBase->Trigger
<Style x:Key="Triggers" TargetType="Button">
<Style.Triggers>
<Trigger Property="IsPressed" Value="true">
<Setter Property = "Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
名称 | 备注 | 权限 |
---|---|---|
Property | 获取或设置一个属性,该属性返回要与触发器的 Value 属性进行比较的值。 该比较是一项引用相等性检查。 | get; set; |
Setters | 获取 Setter 对象的集合,这些对象描述当满足指定条件时要应用的属性值。 | get; |
SourceName | 获取或设置对象的名称,该对象具有可应用关联的 setter 的属性。 | get; set; |
Value | 获取或设置要与元素的属性值进行比较的值。 该比较是一项引用相等性检查。 | get; set; |
名称 | 备注 | 权限 |
---|---|---|
ReceiveTypeConverter | 处理类型转换器为 Trigger 对象的属性提供值的情况。 | public |
名称 | 备注 | 方法 |
---|---|---|
ISupportInitialize.BeginInit | 用信号通知对象初始化即将开始。 | void ISupportInitialize.BeginInit (); |
ISupportInitialize.EndInit | 用信号通知对象初始化已完成。 | void ISupportInitialize.EndInit (); |
IAddChild.AddChild | 添加子对象。 | void IAddChild.AddChild (object value); |
IAddChild.AddText | 将节点的文本内容添加到对象。 | void IAddChild.AddText (string text); |
-
MultiTrigger
Object->DispatcherObject->DependencyObject->TriggerBase->MultiTrigger
<Style.Triggers>
<Trigger Property="IsEnabled" Value="false">
<Setter Property="Background" Value="#EEEEEE" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasItems" Value="false" />
<Condition Property="Width" Value="Auto" />
</MultiTrigger.Conditions>
<Setter Property="MinWidth" Value="120"/>
</MultiTrigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="HasItems" Value="false" />
<Condition Property="Height" Value="Auto" />
</MultiTrigger.Conditions>
<Setter Property="MinHeight" Value="95"/>
</MultiTrigger>
</Style.Triggers>
名称 | 备注 | 权限 |
---|---|---|
Conditions | 获取 Condition 对象的集合。 当满足集合中的所有条件时对属性值应用更改。 | get; |
Setters | 获取 Setter 对象的集合,这些对象描述当满足 MultiTrigger 的所有条件时要应用的属性值。 | get; |
名称 | 备注 | 方法 |
---|---|---|
IAddChild.AddChild | 添加子对象。 | void IAddChild.AddChild (object value); |
IAddChild.AddText | 将节点的文本内容添加到对象。 | void IAddChild.AddText (string text); |
-
DataTrigger
Object->DispatcherObject->DependencyObject->TriggerBase->DataTrigger
<Window.Resources>
<c:Places x:Key="PlacesData"/>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=State}" Value="WA">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=Name}" Value="Portland" />
<Condition Binding="{Binding Path=State}" Value="OR" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Cyan" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type c:Place}">
<Canvas Width="160" Height="20">
<TextBlock FontSize="12"
Width="130" Canvas.Left="0" Text="{Binding Path=Name}"/>
<TextBlock FontSize="12" Width="30"
Canvas.Left="130" Text="{Binding Path=State}"/>
</Canvas>
</DataTemplate>
</Window.Resources>
<StackPanel>
<TextBlock FontSize="18" Margin="5" FontWeight="Bold"
HorizontalAlignment="Center">Data Trigger Sample</TextBlock>
<ListBox Width="180" HorizontalAlignment="Center" Background="Honeydew"
ItemsSource="{Binding Source={StaticResource PlacesData}}"/>
</StackPanel>
名称 | 备注 | 权限 |
---|---|---|
Binding | 获取或设置产生数据对象的属性值的绑定。 | get; set; |
Setters | 获取 Setter 对象的集合,这些对象描述当数据项满足指定条件时要应用的属性值。 | get; |
Value | 获取或设置要与数据对象的属性值比较的值。 | get; set; |
名称 | 备注 | 权限 |
---|---|---|
ReceiveMarkupExtension | 处理标记扩展为 DataTrigger 对象的属性提供值的情况。 | public |
名称 | 备注 | 方法 |
---|---|---|
IAddChild.AddChild | 添加子对象。 | void IAddChild.AddChild (object value); |
IAddChild.AddText | 将节点的文本内容添加到对象。 | void IAddChild.AddText (string text); |
-
MultiDataTrigger
Object->DispatcherObject->DependencyObject->TriggerBase->MultiDataTrigger
<Window.Resources>
<c:Places x:Key="PlacesData"/>
<Style TargetType="ListBoxItem">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=State}" Value="WA">
<Setter Property="Foreground" Value="Red" />
</DataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding Path=Name}" Value="Portland" />
<Condition Binding="{Binding Path=State}" Value="OR" />
</MultiDataTrigger.Conditions>
<Setter Property="Background" Value="Cyan" />
</MultiDataTrigger>
</Style.Triggers>
</Style>
<DataTemplate DataType="{x:Type c:Place}">
<Canvas Width="160" Height="20">
<TextBlock FontSize="12"
Width="130" Canvas.Left="0" Text="{Binding Path=Name}"/>
<TextBlock FontSize="12" Width="30"
Canvas.Left="130" Text="{Binding Path=State}"/>
</Canvas>
</DataTemplate>
</Window.Resources>
<StackPanel>
<TextBlock FontSize="18" Margin="5" FontWeight="Bold"
HorizontalAlignment="Center">Data Trigger Sample</TextBlock>
<ListBox Width="180" HorizontalAlignment="Center" Background="Honeydew"
ItemsSource="{Binding Source={StaticResource PlacesData}}"/>
</StackPanel>
名称 | 备注 | 权限 |
---|---|---|
Conditions | 获取 Condition 对象的集合。 在满足集合中的所有条件时应用对属性值的更改。 | get |
Setters | 获取 Setter 对象的集合,这些对象描述在满足 MultiDataTrigger 的所有条件时应用的属性值。 | get |
名称 | 备注 | 方法 |
---|---|---|
IAddChild.AddChild | 添加子对象。 | void IAddChild.AddChild (object value); |
IAddChild.AddText | 将节点的文本内容添加到对象。 | void IAddChild.AddText (string text); |
-
EventTrigger
Object->DispatcherObject->DependencyObject->TriggerBase->EventTrigger
<Style TargetType="Rectangle">
<Setter Property="Width" Value="50" />
<Setter Property="Height" Value="50" />
<Setter Property="Margin" Value="20" />
<Setter Property="HorizontalAlignment" Value="Left" />
<Style.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation To="300" Duration="0:0:1.5"
AccelerationRatio="0.10" DecelerationRatio="0.25"
Storyboard.TargetProperty="(Canvas.Width)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Duration="0:0:1.5"
AccelerationRatio="0.10" DecelerationRatio="0.25"
Storyboard.TargetProperty="(Canvas.Width)" />
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
名称 | 备注 | 权限 |
---|---|---|
Actions | 获取事件发生时要应用的操作的集合。 | get; |
RoutedEvent | 获取或设置将激活该触发器的 RoutedEvent。 | get; set; |
SourceName | 获取或设置对象的名称,该对象具有激活此触发器的事件。 仅元素触发器或模板触发器可使用此名称。 | get; set; |
名称 | 备注 | 权限 |
---|---|---|
AddChild | 将指定的对象添加到当前事件触发器的 Actions 集合中。 | protected |
AddText | 此方法不受支持并导致异常。 | protected |
ShouldSerializeActions | 返回序列化进程是否应序列化此类的实例上 Actions 属性的有效值。 | public |
IAddChild.AddChild | 添加子对象。 | void IAddChild.AddChild (object value); |
IAddChild.AddText | 将节点的文本内容添加到对象。 | void IAddChild.AddText (string text); |
行为Behavior
- 添加对System.Windows.Interactivity的引用
- 创建一个继承自Behavior的派生类。
- 实现OnAttached()、OnDetaching()和其他方法。
public class EffectBehavior : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.MouseMove += AssociatedObject_MouseMove;
AssociatedObject.MouseLeave += AssociatedObject_MouseLeave;
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.MouseMove -= AssociatedObject_MouseMove;
AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave;
}
}
- 在事件处理程序中运行适当的代码。
- XMAL中对类库(如果是这种方式)和System.Windows.Interactivity程序集的引用
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
- 对元素附加效果。
<TextBox Width="100" Height="30" Margin="40">
<i:Interaction.Behaviors>
<local:EffectBehavior/>
</i:Interaction.Behaviors>
</TextBox>
范例
EffectBehavior.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Interactivity;
using System.Windows.Media;
using System.Windows.Media.Effects;
namespace EffectBehaviorDemo
{
public class EffectBehavior : Behavior<FrameworkElement>
{
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.MouseMove += AssociatedObject_MouseMove;
AssociatedObject.MouseLeave += AssociatedObject_MouseLeave;
}
private void AssociatedObject_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e)
{
var element = sender as FrameworkElement;
element.Effect = (Effect)new DropShadowEffect() { Color = Colors.Transparent, ShadowDepth = 0 };
}
private void AssociatedObject_MouseMove(object sender, System.Windows.Input.MouseEventArgs e)
{
var element = sender as FrameworkElement;
element.Effect = (Effect)new DropShadowEffect() { Color = Colors.Red, ShadowDepth = 10 };
}
protected override void OnDetaching()
{
base.OnDetaching();
AssociatedObject.MouseMove -= AssociatedObject_MouseMove;
AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave;
}
}
}
MainWindow.xaml
<Window
x:Class="EffectBehaviorDemo.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:EffectBehaviorDemo"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Title="MainWindow"
Width="800"
Height="450"
mc:Ignorable="d">
<Grid>
<StackPanel>
<TextBox Width="100" Height="30" Margin="40">
<i:Interaction.Behaviors>
<local:EffectBehavior/>
</i:Interaction.Behaviors>
</TextBox>
<Button Width="100" Height="30" Margin="40">
<i:Interaction.Behaviors>
<local:EffectBehavior/>
</i:Interaction.Behaviors>
</Button>
<!--<i:Interaction.Behaviors>
<local:EffectBehavior/>
</i:Interaction.Behaviors>-->
</StackPanel>
</Grid>
</Window>
MainWindow.xaml.cs
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace EffectBehaviorDemo
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
}
}