none
WPF Application XAML 中Style(皮肤样式)机制详解 RRS feed

  • 常规讨论

  • 日期:2008-3-5作者:由灵
    皮肤样式是由Windows Presentation Foundation中的控件基类(FrameworkElement、FrameworkContentElement)中的换肤机制,使得程序的逻辑层和表示层独立!也是XAML实现“面向对象编程”思路的方法,一个控件中Style属性包含着一个Style对象,当Style对象更改时就可更新控件的大小及颜色等属性。Style对象对表示层中还包括鼠标上去事件时的变化,和动画等的支持!这一系列数据组成一个Style对象,并可以把这个Style对象应用到多个控件。

      XAML对Style的支持很好,一般请况Style初始化在父控件的Resources标记里面做为一个资源等待调用。例如:

     <Window
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="WPFHOME Application" Height="100" Width="359">

         <Window.Resources>
             <Style TargetType="{x:Type Button}">
                 <Setter Property="Background" Value="Blue"/>
                 <Setter Property="Foreground" Value="White"/>
             </Style>
             <Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}" x:Key="style2">
                 <Setter Property="Background" Value="Red"/>
             </Style>
     
         </Window.Resources>
         <DockPanel>
             <Button Name="button1" Width="179.5">Button1</Button>
             <Button Name="button2" Style="{StaticResource style2}">Button2</Button>
         </DockPanel>
     </Window>

      其中Style节在父控件Window的Resources属性中,表意Window下所有的子控件都可以获取Window.Resources中的对象。其中第一个Style没有制定x:Key属性,这样会作为默认样式,应用到全部的没套用Button类型的控件上。而style2样式中使用了BaseOn属性继承了默认皮肤中的Foreground,而且重写了Background。如果第1个style不是默认Style制定了x:key="style1",第2个Style中的BaseOn应改为BaseOn={StaticResource style1}同样可以继承第一个皮肤。

      其中Style的执行级别比较低,如果使用Style的控件中赋过值的属性(更改默认值),其Style中的Setter将不会起作用!例如:

     <Window
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="WPFHOME Application" Height="100" Width="359">

         <Window.Resources>
             <Style TargetType="{x:Type Button}">
                 <Setter Property="Background" Value="Blue"/>
                 <Setter Property="Foreground" Value="White"/>
             </Style>
             <Style TargetType="{x:Type Button}" BasedOn="{StaticResource {x:Type Button}}" x:Key="style2">
                 <Setter Property="Background" Value="Red"/>
             </Style>
     
         </Window.Resources>
         <DockPanel>
             <Button Name="button1" Width="179.5">Button1</Button>
             <Button Name="button2" Style="{StaticResource style2}" Background="Black">Button2</Button>
         </DockPanel>
     </Window>

      这段代码中,button2设定了Background为Black。然后皮肤中的设定将会失效!

      <Window
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          Title="WPFHOME Application" Height="100" Width="359">

         <Window.Resources>
             <Style TargetType="{x:Type Button}">
                 <Setter Property="Background" Value="Blue"/>
                 <Setter Property="Foreground" Value="White"/>
                 <Setter Property="Content" Value="按扭"/>
                 <Style.Triggers>
                     <EventTrigger RoutedEvent="MouseEnter">
                         <BeginStoryboard>
                             <Storyboard>
                                 <ColorAnimationUsingKeyFrames BeginTime="00:00:00"  Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                     <SplineColorKeyFrame KeyTime="00:00:00.8" Value="#FFEE00C8"/>
                                 </ColorAnimationUsingKeyFrames>
                             </Storyboard>
                         </BeginStoryboard>
                     </EventTrigger>
                     <EventTrigger RoutedEvent="MouseLeave">
                         <BeginStoryboard>
                             <Storyboard>
                                 <ColorAnimationUsingKeyFrames BeginTime="00:00:00"  Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)">
                                     <SplineColorKeyFrame KeyTime="00:00:00.8" Value="Blue"/>
                                 </ColorAnimationUsingKeyFrames>
                             </Storyboard>
                         </BeginStoryboard>
                     </EventTrigger>
                     <Trigger Property="IsMouseOver" Value="True">
                         <Setter Property="Content" Value="WPF之家欢迎您"/>
                     </Trigger>
                 </Style.Triggers>
             </Style>
         </Window.Resources>
         <DockPanel>
             <Button Name="button1" Width="179.5"></Button>
             <Button Name="button2"></Button>
         </DockPanel>
     </Window>

      这段代码中实现了Style中事件出发动画的播放和改变文字内容的方法。Style.Triggers是一个Trigger(触发器)集合。然后使用了EventTrigger(事件触发器)中播放了变颜色的动画效果。然后由Trigger(属性触发器)出发改变文字内容,其中Trigger在不符合Value中的值是会撤消Setter中的操作!在动画节请参见:Storyboard(故事面板)动画篇。

      Trigger属性触发器

      Trigger是当目标对象中Dependency的属性发生变时,检测Trigger标记中的Property属性是否与更新的属性相同,并且Trigger标记中的Value值相同则执行子标记中的Setter。

      EventTrigger(事件触发器)

      当事件触发时执行,可以包括动画显示的操作!

    2009年6月19日 2:03