模板

如果把WPF窗体看做一个舞台的话,窗体上的控件就是演员,他们的职责就是在用户界面上按照业务逻辑的需呀哦扮演自己的角色。为了让同一个控件担当起不同的角色,程序员就要为他们设计多种外观样式和行为动作。这就是Style。构成Style 的两个重要元素就是Setter和Trigger,Setter是用来设置控件的静态外观风格,Trigger是用来设置控件的行为风格。

<Style x:Key="ListBoxOCTStyle" TargetType="{x:Type ListBox}">
<Setter Property="Background" Value="{StaticResource ListBoxPopBackgroundBrush}" />
<Setter Property="BorderBrush" Value="{StaticResource ListBoxPopBorderBrush}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Auto" />
<Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Visible" />
<Setter Property="ScrollViewer.CanContentScroll" Value="true" />
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBox}">
<Border
Padding="1"
Background="{TemplateBinding Background}"
BorderBrush="{TemplateBinding BorderBrush}"
BorderThickness="{TemplateBinding BorderThickness}"
SnapsToDevicePixels="true">
<ScrollViewer
Padding="{TemplateBinding Padding}"
Focusable="false"
Template="{StaticResource ScrollViewerControlTemplate}">
<ItemsPresenter SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</ScrollViewer>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Resources>
<Style BasedOn="{StaticResource ListBoxOCTItemStyle}" TargetType="ListBoxItem" />
</Style.Resources>
</Style>

根据上面的例子我们可以看出,如果想设置控件的ControlTemplate,只需要把Setter的Property设置为Template并为Value提供一个ControlTemplate对象即可。

Trigger(触发器)即当某些条件满足时会触发一个行为(比如某些值的变化或者动画的发生等),触发器比较像事件。事件一般是由用户操作触发的,而触发器除了事件触发型 的EventTrigger外,还有数据变化触发型的Trigger/DataTrigger及多条件触发型的MultiTrigger/MultiDataTrigger等。

1)基本触发器Trigger:类似于Setter,也有Property和Value两个属性,Property是Trigger关注的属性名称,Value是触发条件。一旦满足这个条件,对应的值就会被应用,触发条件不满足时,各属性值就会被还原。

<Style x:Key="ListBoxOCTItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="Background" Value="Transparent" />
<Setter Property="Width" Value="Auto" />
<Setter Property="Height" Value="Auto" />
<Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
<Setter Property="Padding" Value="0" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="BorderBrush" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="ContentTemplate" Value="{StaticResource ListBoxItemOCTDataTemplate}" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border
x:Name="Bd"
Margin="0,1"
Padding="{TemplateBinding Padding}"
Background="{StaticResource ItemSelectedBackground}"
BorderBrush="{StaticResource ItemSelectedBackground}"
BorderThickness="2,2,2,2"
CornerRadius="5"
SnapsToDevicePixels="true">
<Grid x:Name="grid">
<ContentPresenter
Margin="{TemplateBinding Padding}"
HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}"
VerticalAlignment="{TemplateBinding VerticalContentAlignment}"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
</Grid>
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="Foreground" Value="{StaticResource CommonForeground}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="YellowGreen" />
<Setter TargetName="Bd" Property="BorderThickness" Value="2,2,2,2" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="Foreground" Value="{StaticResource CommonForeground}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="#FF126BAA" />
<Setter TargetName="Bd" Property="BorderThickness" Value="2,2,2,2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<!--<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}"/>-->
<!--<Setter Property="Foreground" Value="{StaticResource CommonForeground}"/>-->
<!--<Setter Property="BorderBrush" Value="YellowGreen"/>
<Setter Property="BorderThickness" Value="2,2,2,2"/>-->
</Trigger>
<Trigger Property="IsSelected" Value="True">
<!--<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}"/>-->
<!--<Setter Property="Foreground" Value="{StaticResource CommonForeground}"/>-->
<!--<Setter Property="BorderBrush" Value="#FF126BAA"/>-->
<!--<Setter Property="BorderThickness" Value="2,2,2,2"/>-->
</Trigger>
</Style.Triggers>
</Style>

2)MultiTrigger,类似于MultiBinding,只有多条件都满足时才会触发。MultiTrigger比Trigger多了一个Conditions属性,需要同时满足的条件就放在这个集合中。

<Style x:Key="DataGridScrollBarEverShowStyle" TargetType="DataGrid">
<Setter Property="Background" Value="{DynamicResource SecondaryRegionBrush}" />
<Setter Property="BorderBrush" Value="{DynamicResource BorderBrush}" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="GridLinesVisibility" Value="None" />
<Setter Property="RowDetailsVisibilityMode" Value="VisibleWhenSelected" />
<Setter Property="ScrollViewer.CanContentScroll" Value="True" />
<Setter Property="ScrollViewer.PanningMode" Value="Both" />
<Setter Property="VerticalScrollBarVisibility" Value="Visible" />
<Setter Property="HorizontalScrollBarVisibility" Value="Visible" />
<Setter Property="Stylus.IsFlicksEnabled" Value="False" />
<Setter Property="EnableRowVirtualization" Value="True" />
<Setter Property="CanUserAddRows" Value="False" />
<Setter Property="CanUserDeleteRows" Value="False" />
<Setter Property="CanUserReorderColumns" Value="False" />
<Setter Property="CanUserResizeRows" Value="False" />
<Setter Property="CanUserResizeColumns" Value="False" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="DataGrid">
<Border
……
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
<Style.Triggers>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsGrouping" Value="true" />
<Condition Property="VirtualizingPanel.IsVirtualizingWhenGrouping" Value="false" />
</MultiTrigger.Conditions>
<Setter Property="ScrollViewer.CanContentScroll" Value="false" />
</MultiTrigger>
</Style.Triggers>
</Style>

3)由数据触发的DataTrigger:程序中经常会遇到基于数据执行某些判断的情况,遇到这种情况时我们可以考虑使用DataTrigger。DataTrigger对象Binding属性会把数据源不断的送过来,一旦送来的值与Value值一致时,DataTrigger就会触发。

<!--  ItemsControl分组  -->
<Style x:Key="GroupContainerStyle" TargetType="{x:Type GroupItem}">
<Setter Property="HorizontalContentAlignment" Value="Center" />
<Setter Property="VerticalContentAlignment" Value="Center" />
<Setter Property="Width" Value="200" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type GroupItem}">
<ControlTemplate.Triggers>
<DataTrigger Binding="{Binding Path=IsBottomLevel}" Value="True">
<Setter TargetName="gridTemplate" Property="Grid.Background" Value="Gray" />
</DataTrigger>
</ControlTemplate.Triggers>
<Border BorderBrush="{StaticResource CommonBackground}" BorderThickness="0,2,0,0">
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Grid
x:Name="gridTemplate"
Width="{TemplateBinding Width}"
Height="40"
HorizontalAlignment="Center"
VerticalAlignment="Center"
Background="{StaticResource DarkBackground}">
<Border
Height="Auto"
Margin="0"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
BorderBrush="Black"
BorderThickness="0">
<ToggleButton
x:Name="btnShowHide"
Width="Auto"
Height="Auto"
IsChecked="True"
Style="{StaticResource ToggleButtonStyle}" />
</Border>
<!--<Label Content="{Binding Path=Name}" Grid.Column="0" VerticalContentAlignment="Center"/>-->
<!--<Label VerticalContentAlignment="Center" HorizontalContentAlignment="Right" Grid.Column="1" Content="{Binding Path=ItemCount, StringFormat=Total:{0}}"/>-->
</Grid>
<ItemsPresenter
Grid.Row="1"
Margin="0"
Visibility="{Binding ElementName=btnShowHide, Path=IsChecked, Converter={StaticResource booleanToVisibilityConverter}}" />
</Grid>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>

4)多数据条件触发的MultiDataTrigger:当多个数据条件满足时就会触发的情况下,就可以使用多数据条件触发器。这里结合多条件触发器和数据触发器就可以很容易理解了。

5)事件触发器EventTrigger:事件触发器比较特殊,首先,他不是属性值或者数据的变化来触发而是由事件触发的;其次,被触发后并非应用一组Setter,而是执行一段动画

<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="MouseEnter">
<BeginStoryboard Storyboard="{StaticResource Storyboard1}"/>
</EventTrigger>
<EventTrigger RoutedEvent="MouseLeave">
<BeginStoryboard Storyboard="{StaticResource Storyboard2}"/>
</EventTrigger>
</ControlTemplate.Triggers>

有上面的这些代码可以看出,触发器不一定非要应用在Style中,在Template中也可以使用触发器。比如:

<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="Foreground" Value="{StaticResource CommonForeground}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="YellowGreen" />
<Setter TargetName="Bd" Property="BorderThickness" Value="2,2,2,2" />
</Trigger>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Background" Value="{StaticResource ItemSelectedBackground}" />
<Setter Property="Foreground" Value="{StaticResource CommonForeground}" />
<Setter TargetName="Bd" Property="BorderBrush" Value="#FF126BAA" />
<Setter TargetName="Bd" Property="BorderThickness" Value="2,2,2,2" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>

最新文章

  1. Unsupported major.minor version 52.0问题的解决
  2. 跟着ttlsa一起学zabbix监控呗
  3. 【C语言入门教程】4.5 指针变量的定义与引用
  4. hdu----1686 Oulipo (ac自动机)
  5. 白盒测试的学习之路----(五)TestNG的参数分离
  6. C++ Vector 用法总结
  7. ORACLE-RAC-11G-R2_INSTALL
  8. Device Tree常用方法解析
  9. sum(case when then)(男女生的个数)
  10. 关于Platinum库的MediaRender具体C++代码实现探讨
  11. mysql存储过程且mybatis调用
  12. Java的selenium代码随笔(2)
  13. 如何用ABP框架快速完成项目 - 自动化测试 - 前端angular e2e protractor
  14. Python 魔法方法简介
  15. 使用CROS解决跨域问题
  16. 个人博客Week3——案例分析
  17. python slots
  18. dp 二维乃至多维背包
  19. 免费通配符SSL证书
  20. Delphi-idHttp-Post JSON用法 good

热门文章

  1. JAVA集合类(代码手写实现,全面梳理)
  2. CPU 进程 线程 关系与区别
  3. C#中的集合类
  4. Mybatis轻松入门(仅要求会用看着一个就够了,略过源码分析部分即可)
  5. hystrix熔断机制修改配置
  6. python画循环圆
  7. 详解 Interpolator动画插值器
  8. mysql索引基本介绍
  9. vscode Markdown Preview Enhanced 安装配置
  10. OpenCV 传统分割测试