• 星空雅梦


    WPF教程(八)样式入门一

    样式是我认为WPF中一块极为重要的知识,也体现该种框架比较厉害之处:(1)UI设计与动画方面的炫丽;(2)XMAL代码的引入使得代码的编写能够前后端分离,这种都是传统界面框架都不能比拟的,比如Winform、C++的MFC。我认为这是微软向当前We前端开发模式的学习,WPF是过渡的框架。当然,这些都是题外话。

    WPF的样式是非常强大的,除了与HTML标记中的CSS类似,它还能够支持触发器(Trigger),比如当元素属性发生变化时,可通过触发器改变控件样式,但本文中暂不涉及触发器(下一篇博客里写)。特基础的不讲了,先看下事件关联例子。

    1.  
      <Window x:Class="Style.MainWindow"
    2.  
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3.  
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4.  
      Title="MainWindow" Height="350" Width="525">
    5.  
      <Window.Resources>
    6.  
      <Style x:Key="textblockstyle" TargetType="TextBlock">
    7.  
      <Setter Property="HorizontalAlignment" Value="Center"/>
    8.  
      <Setter Property="TextAlignment" Value="Center"/>
    9.  
      <Setter Property="Padding" Value="5"/>
    10.  
      <EventSetter Event="TextBlock.MouseEnter" Handler="element_mouseEnter"/>
    11.  
      <EventSetter Event="TextBlock.MouseLeave" Handler="element_mouseLeave"/>
    12.  
      </Style>
    13.  
      </Window.Resources>
    14.  
      <Grid>
    15.  
      <WrapPanel>
    16.  
      <TextBlock Style="{StaticResource textblockstyle}" Text="helloworld"/>
    17.  
      </WrapPanel>
    18.  
      </Grid>
    19.  
      </Window>
    1.  
      public partial class MainWindow : Window
    2.  
      {
    3.  
      public MainWindow()
    4.  
      {
    5.  
      InitializeComponent();
    6.  
      }
    7.  
      private void element_mouseEnter(object sender, MouseEventArgs e)
    8.  
      {
    9.  
      ((TextBlock)sender).Background = new SolidColorBrush(Colors.Aqua);
    10.  
      }
    11.  
      private void element_mouseLeave(object sender, MouseEventArgs e)
    12.  
      {
    13.  
      ((TextBlock)sender).Background = null;
    14.  
      }
    15.  
      }

    这种事件关联仍是没有实现软件的低耦合性,没发挥出WPF高端之处。当然,在后续触发器(Trigger)介绍,就可以打破这种尴尬的境况,下面介绍样式的多层继承。

    1.  
      <Window x:Class="Style.MainWindow"
    2.  
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3.  
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4.  
      Title="MainWindow" Height="350" Width="525">
    5.  
      <Window.Resources>
    6.  
      <Style x:Key="textblockstyle" TargetType="TextBlock">
    7.  
      <Setter Property="HorizontalAlignment" Value="Center"/>
    8.  
      <Setter Property="TextAlignment" Value="Center"/>
    9.  
      <Setter Property="Padding" Value="5"/>
    10.  
      <EventSetter Event="TextBlock.MouseEnter" Handler="element_mouseEnter"/>
    11.  
      <EventSetter Event="TextBlock.MouseLeave" Handler="element_mouseLeave"/>
    12.  
      </Style>
    13.  
      <Style x:Key="BaseOnStyle"
    14.  
      TargetType="TextBlock"
    15.  
      BasedOn="{StaticResource textblockstyle}">
    16.  
      <Setter Property="Control.Foreground" Value="Red"/>
    17.  
      </Style>
    18.  
      </Window.Resources>
    19.  
      <Grid>
    20.  
      <WrapPanel>
    21.  
      <TextBlock Style="{StaticResource textblockstyle}" Text="helloworld"/>
    22.  
      <TextBlock Text="Inherited Style TextBlock" Style="{StaticResource BaseOnStyle}"/>
    23.  
      </WrapPanel>
    24.  
      </Grid>
    25.  
      </Window>
    26.  
      //注释:后台代码不变

    这里提个小技巧,隐藏键值可以自动将样式用到元素树上所有该类控件上,注意下面程序如何隐藏键值,大有玄机,里面涉及到一些知识点。

    1.  
      <Window x:Class="Style.MainWindow"
    2.  
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3.  
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4.  
      Title="MainWindow" Height="350" Width="525">
    5.  
      <Window.Resources>
    6.  
      <Style x:Key="{x:Type TextBlock}">
    7.  
      <!--隐式设置为 {x:Type TextBlock}-->
    8.  
      <!--<Style TargetType="TextBlock">-->
    9.  
      <Setter Property="Control.Foreground" Value="Pink"/>
    10.  
      <Setter Property="TextBlock.FontSize" Value="18"/>
    11.  
      </Style>
    12.  
      </Window.Resources>
    13.  
      <Grid>
    14.  
      <WrapPanel>
    15.  
      <TextBlock Text="hello"/>
    16.  
      <TextBlock Text="hi"/>
    17.  
      <TextBlock Style="{x:Null}" Text="good"/>
    18.  
      </WrapPanel>
    19.  
      </Grid>
    20.  
      </Window>

    仔细分析,总结出5个知识点:

    1. 显示设置隐藏键值,后面TargetType可以写,也可以不写。上段程序显然没写出来,这涉及到知识点3,先注意写法。

    2. 隐式设置隐藏键值,请看注释掉的部分,TargetType必须写明,这样相当于隐藏了{x:Type TextBlock},效果是跟第一点显示设置一样的,都可以用到元素树中此类控件,先注意写法,也涉及知识点3。

    3. 如果是没有写出TargeType样式类型,必须用类名来限制Setter对象的Property属性值,否则报错。上面程序,显然加TextBlock和Control类名,如果指明了,可写可不写类名。

    4. 如果某一此类控件不想用指定样式,可以将Style置Null重新写此属性或直接重新写此属性,都可覆盖原资源里的设置。

    5. 同一范围不能重复定义相同key样式,包括相同(显式/隐式)隐藏键值。

    如果希望在多个样式中(或在同一样式的多个设置器中)重用相同的属性值,可以将其定义为资源,然后再在样式中使用资源:

    1.  
      <Window.Resources>
    2.  
      <Brush x:Key="brush" >Black</Brush>
    3.  
      <Style x:Key="{x:Type TextBlock}">
    4.  
      <Setter Property="Control.Foreground" Value="{StaticResource brush}"/>
    5.  
      <Setter Property="TextBlock.FontSize" Value="18"/>
    6.  
      </Style>
    7.  
      </Window.Resources>

    在WPF中还存在这样一些情况,在元素框架层次中(不管是否有TargetType属性)的多个位置定义了同一个属性。例如,在Control类和TextBlock类,中都定义了全部的字体颜色属性。

    1.  
      <Window.Resources>
    2.  
      <Style x:Key="foreground">
    3.  
      <Setter Property="TextBlock.Foreground" Value="Yellow"/>
    4.  
      <Setter Property="Button.Foreground" Value="Yellow"/>
    5.  
      </Style>
    6.  
      </Window.Resources>

    不管是哪个控件,只要支持这个属性,都可以引用这个字色样式,那会使用哪个色体呢?尽管TextBlock.FontFamily属性和Button.FontFamily属性是在他们各自的基类中分别声明,但它们都引用同一个依赖项属性。所以,当使用这个样式时,WPF设置Foreground属性两次,最后应用的设置具有优先权。

    总结

    Style样式如果不加TargetType,其它控件都可以使用该样式。如果加了目标类型,其它控件引用直接回报错。如果显示设置隐藏键值,只是不会作用于其它控件,两者还是有区分的

    样式的基本使用知识点大致就上面几点,深层去剖析,涉及到依赖属性这个难点,我也有详细介绍过这块知识,有兴趣的朋友可以去看看,下面介绍样式的第二个重点Trigger。

  • 相关阅读:
    Java 基础
    Java 数据类型
    Spring 拦截器实现事物
    SSH 配置日记
    Hibernate 知识提高
    Jsp、Servlet
    leetcode 97. Interleaving String
    leetcode 750. Number Of Corner Rectangles
    leetcode 748. Shortest Completing Word
    leetcode 746. Min Cost Climbing Stairs
  • 原文地址:https://www.cnblogs.com/LiZhongZhongY/p/10870492.html
Copyright © 2020-2023  润新知