• 星空雅梦


    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。

  • 相关阅读:
    vue-cli + webpack 构建vue.js开发环境
    JDK、Eclipse、Myeclipse、Tomcat等各种软件的版本详解(写给对版本和兼容性问题焦头烂额的你)
    总结下var、let 和 const 的区别
    vue双向绑定原理
    Vue中computed和watch的区别
    前端面试题总结
    微信开发之上传素材
    微信开发之向用户群发文本消息
    微信开发之获取用户详细列表
    TPshop入门大纲
  • 原文地址:https://www.cnblogs.com/LiZhongZhongY/p/10870492.html
Copyright © 2020-2023  润新知