WPF资源

对象资源

WPF允许在XAML标记的任意位置定义资源。比如在特定的控件、窗口或应用程序级别定义资源,WPF资源系统提供的对象资源有如下好处:

1、  高效:使用对象资源可以在一个地方定义而在多个地方使用,这使得WPF代码可重用一些对象信息。

2、  可维护:可以将一些设置信息放置在一个中心位置,并在多个地方使用。如果需要进行更改时,只需要在中心位置进行更改,方便代码的维护工作。

3、  可适应性:当确定的信息从应用程序中分离出来放在资源中,就可以动态地被改变。例如可以基于用户的偏好设置当前语言来更改信息。

下面是一个在Grid级别的资源,设置textblock的字体大小。

<Window x:Class="WPFDemo.Resource_FontSize"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDemo"
xmlns:s="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Resource_FontSize" Height="300" Width="300"
>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!---Grid级别的资源-->
<Grid.Resources>
<s:Double x:Key="SmallSize" >20</s:Double>
<s:Double x:Key="LargeSize">30</s:Double>
</Grid.Resources>
<TextBlock Text="小字体" Grid.Row="0">
<TextBlock.FontSize>
<StaticResource ResourceKey="SmallSize" />
</TextBlock.FontSize>
</TextBlock>
<TextBlock Text="大字体" Grid.Row="1">
<TextBlock.FontSize>
<StaticResource ResourceKey="LargeSize" />
</TextBlock.FontSize>
</TextBlock>
</Grid>
</Window>

  

 

静态资源

静态资源就是上面使用StaticResource标记引用的资源。这种资源一旦被创建就不会被改变。静态资源必须先定义资源,否则会抛出异常。

应用程序资源

应用程序的资源作用域覆盖整个WPF应用程序,WPF将按照元素、窗口、应用程序、系统资源的顺序进行资源查找。当新建一个WPF项目时,在APP.xaml中会自动添加<Application.Resources>标签,可以在标签内添加应用程序级别的资源。

定义BackgroundColor系统资源

<Application x:Class="WPFDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Resource-FontSize.xaml"
>
<Application.Resources>
<SolidColorBrush x:Key="BackgroundColor" Color="Yellow">
</SolidColorBrush>
</Application.Resources>
</Application>

调用BackgrouundColor资源 

在Window标签添加引用  Background="{StaticResource BackgroundColor}"

<Window x:Class="WPFDemo.Resource_FontSize"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDemo"
xmlns:s="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Resource_FontSize" Height="300" Width="300"
Background="{StaticResource BackgroundColor}"
>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!---Grid级别的资源-->
<Grid.Resources>
<s:Double x:Key="SmallSize" >20</s:Double>
<s:Double x:Key="LargeSize">30</s:Double>
</Grid.Resources>
<TextBlock Text="小字体" Grid.Row="0">
<TextBlock.FontSize>
<StaticResource ResourceKey="SmallSize" />
</TextBlock.FontSize>
</TextBlock>
<TextBlock Text="大字体" Grid.Row="1">
<TextBlock.FontSize>
<StaticResource ResourceKey="LargeSize" />
</TextBlock.FontSize>
</TextBlock>
</Grid>
</Window>

使用资源字典组织资源 

可以在一个单独的XAML文件中定义资源,然后该资源可以在多个项目进行共享。独立的资源文件使用ResourceDictionary作为根元素。该XAML文件除了用于存储资源外,不能做任何其他的工作。

下面定义一个线性渐变的背景色

1、  首先新建WPF资源文件添加资源内容

2、  将资源文件设置生成操作位Page以确保资源被作为BAML文件编译。也可以将其指定为Reesource,这种方式将内嵌在程序集中,不被编译,运行时编译,性能开支较大。

3、为了使用该资源,需要将其合并到应用程序资源集合中,可以合并到指定窗口资源集合,但是通常合并到应用程序级别的集合。

新建WPF资源文件并添加内容

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WPFDemo">
<!--定义渐变的背景色-->
<LinearGradientBrush x:Key="brushLinear">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Red" Offset="0" />
<GradientStop Color="Yellow" Offset="0.5" />
<GradientStop Color="Blue" Offset="1" />
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</ResourceDictionary>

将资源文件合并到应用程序资源中

<Application x:Class="WPFDemo.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Resource-FontSize.xaml"
>
<Application.Resources>
<ResourceDictionary>
<SolidColorBrush x:Key="BackgroundColor" Color="Yellow"></SolidColorBrush>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="DictionaryDemo.xaml" />
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>

在上面的例子中增加一个button按钮将其背景颜色设置为渐变

<Window x:Class="WPFDemo.Resource_FontSize"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDemo"
xmlns:s="clr-namespace:System;assembly=mscorlib"
mc:Ignorable="d"
Title="Resource_FontSize" Height="300" Width="300"
Background="{StaticResource BackgroundColor}"
>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<!---Grid级别的资源-->
<Grid.Resources>
<s:Double x:Key="SmallSize" >20</s:Double>
<s:Double x:Key="LargeSize">30</s:Double>
</Grid.Resources>
<TextBlock Text="小字体" Grid.Row="0">
<TextBlock.FontSize>
<StaticResource ResourceKey="SmallSize" />
</TextBlock.FontSize>
</TextBlock>
<TextBlock Text="大字体" Grid.Row="1">
<TextBlock.FontSize>
<StaticResource ResourceKey="LargeSize" />
</TextBlock.FontSize>
</TextBlock>
<Button Grid.Row="2" Content="我是应用静态资源的渐变色">
<Button.Background>
<StaticResource ResourceKey="brushLinear" />
</Button.Background>
</Button>
</Grid>
</Window>

WPF样式

样式是WPF中功能强大的特性,样式基于资源,但是比资源提供了更多重用代码特性。样式与资源相比,提供了额外的好处来使XAML更具可重用性和扩展性。假设在UI中有几个button控件。需要提供3中不同的显示风格。例如不同的FontSize ,FontFamily 和FontWeight 3个属性。此时可能会考虑使用资源的办法,使用该资源可以完成该功能,但是如果每个属性设置3中资源,将会有9中资源出现。在这里使用WPF的样式功能可以轻松解决这些问题。

样式设置优先级:

优先级

描述

元素(高)

元素本身定义的属性具有最高的优先级

样式(中)

在样式中定义的相同属性

父元素(低)

从视觉树的父元素中继承下来的属性

下面实例中会将样式的各种用法都涉及到:主要包括基本的样式、内联样式、在样式中设置属性的复杂应用、根据指定类型自动应用样式。

<Window x:Class="WPFDemo.StyleDemo"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDemo"
mc:Ignorable="d"
Title="StyleDemo" Height="300" Width="300">
<Window.Resources>
<!--基本样式 button 按钮样式-->
<Style x:Key="ButtonStyle">
<Setter Property="Control.FontFamily" Value="楷体"></Setter>
<Setter Property="Control.FontSize" Value="20"></Setter>
</Style>
<!--基本样式 Textblock样式-->
<Style x:Key="TextBlockStyle">
<Setter Property="Control.FontFamily" Value="楷体"></Setter>
<Setter Property="Control.FontSize" Value="40"></Setter>
</Style>
<!--仅限Button使用-->
<Style x:Key="buttonBackgroundColor">
<Setter Property="Button.Background" Value="LightGreen"></Setter>
</Style>
<!--使用TargetType指定样式使用的控件类型 自动套用样式-->
<Style TargetType="{x:Type Label}">
<Setter Property="Foreground" Value="Red"></Setter>
<Setter Property="FontSize" Value="30"></Setter>
</Style>
<!--控件基类样式-->
<Style x:Key="BaseStyle">
<Setter Property="Control.FontSize" Value="20"></Setter>
</Style>
<!--继承BaseStyle-->
<Style x:Key="BaseButtonSyle" BasedOn="{StaticResource BaseStyle}">
<Setter Property="Control.Foreground" Value="Red"></Setter>
<Setter Property="Control.FontWeight" Value="Bold"></Setter>
</Style>
</Window.Resources>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" Content="应用样式按钮" Style="{StaticResource ButtonStyle}"></Button>
<Button Grid.Row="1" FontSize="10" Content="应用样式按钮并设置字体大小" ></Button>
<TextBlock Grid.Row="2" Text="应用样式文本" Style="{StaticResource TextBlockStyle}"></TextBlock>
<TextBlock Grid.Row="3" Text="没有应用样式文本" ></TextBlock>
<Button Grid.Row="4" FontSize="10" Content="使用内联样式设置字体为红色 背景为黄色" >
<!--内联样式-->
<Button.Style>
<Style>
<Setter Property="Control.Foreground" Value="Red"></Setter>
<Setter Property="Control.Background" Value="Yellow"></Setter>
</Style>
</Button.Style>
</Button>
<Button Grid.Row="5" Content="设置背景色为渐变(在样式中使用属性)">
<!--样式中使用属性-->
<Button.Style>
<Style>
<Setter Property="Button.Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Red" Offset="0"/>
<GradientStop Color="Yellow" Offset="0.5"/>
<GradientStop Color="Blue" Offset="1"/>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
<Button Grid.Row="6" Content="我是button,我设置了button样式 - 背景为LightGreen,起作用" Style="{StaticResource buttonBackgroundColor}"></Button>
<TextBlock Grid.Row="7" Text="我是textblock,我设置了button样式 - 背景为LightGreen;不起作用" Style="{StaticResource buttonBackgroundColor}"></TextBlock>
<Label Grid.Row="8" Content="我是Label,Target设置Label 我自动套用Label样式 字体为30 字体为红色"></Label>
<Button Grid.Row="9" Style="{StaticResource BaseButtonSyle}" Content="我使用的是继承样式"></Button>
</Grid>
</Window>

样式触发器

Style类提供了Triggers集合,每个样式可以有多个触发器,每个触发器是一个派生自System.Windows.TriggerBase类的实例。在WPF中,继承自TriggerBase的触发器有下面的类型(属性触发器、数据触发器、事件触发器):

1、Trigger:简单触发器,该触发器检查特定的依赖的属性的值是否发生变化来使用Setter改变样式。

2、MultiTrigger:类似于简单触发器,但是组合了多个条件,所有的条件必须被满足才会改变样式。

3、DataTrigger:与简单触发器类似,该触发器与数据绑定一起运行。但是该触发器是检测任何绑定的数据是否发生变化。

4、MultiDataTrigger:组合了多个DataTrigger。

5、EventTrigger:这是最常用的触发器,当某个事件触发时来改变样式。

在触发器中如果多个触发器修改相同的属性,则最后触发的触发器优先。

<Window x:Class="WPFDemo.StyleTriggerDemo"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDemo"
mc:Ignorable="d"
Title="StyleTriggerDemo" Height="300" Width="300">
<Window.Resources>
<!--属性触发器 按下鼠标后字体增大 按钮旋转20度-->
<Style x:Key="buttonStyle" TargetType="{x:Type Button}">
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="RenderTransform">
<Setter.Value>
<RotateTransform Angle="20" />
</Setter.Value>
</Setter>
<Setter Property="Foreground" Value="Black"/>
<Setter Property="FontSize" Value="20"></Setter>
</Trigger>
</Style.Triggers>
<Setter Property="FontSize" Value="10"></Setter>
<Setter Property="Foreground" Value="White"/>
<Setter Property="Background" Value="#FF87F16F"/>
<Setter Property="Width" Value="100"></Setter>
<Setter Property="Height" Value="50" />
</Style> <!--多条件属性触发器 鼠标经过时显示字体颜色为黄色;鼠标按下并且字体为20时设置字体颜色为红色-->
<Style x:Key="buttonStyle-Multi" TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="20" />
<Style.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="Yellow" />
</Trigger>
<MultiTrigger>
<MultiTrigger.Conditions>
<Condition Property="IsPressed" Value="True"/>
<Condition Property="FontSize" Value="20"/>
</MultiTrigger.Conditions>
<MultiTrigger.Setters>
<Setter Property="Foreground" Value="Red"></Setter>
</MultiTrigger.Setters>
</MultiTrigger>
</Style.Triggers> </Style> <!--事件触发器-->
<Style x:Key="buttonClickStyle">
<Setter Property="Control.FontSize" Value="20"></Setter>
<!--定义事件触发器-->
<Style.Triggers>
<EventTrigger RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<DoubleAnimation Storyboard.TargetProperty="Opacity" From="0.1" To="1" Duration="0:0:2"></DoubleAnimation>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Style.Triggers>
</Style>
<!--数据触发器-->
<Style x:Key="DataTextTrigger">
<!---将控件的背景色设置为文本框中输入的颜色-->
<Setter Property="Control.Background" Value="{Binding RelativeSource={RelativeSource Self},Path=Text}"></Setter>
<Style.Triggers>
<!--当文本中输入的字符超过20时,则文本框的Enable为false-->
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Self},Path=Text.Length}" Value="20">
<Setter Property="Control.IsEnabled" Value="False"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
<!--多条件数据触发器-->
<Style x:Key="DataTextTrigger-Multi">
<Setter Property="Control.FontSize" Value="20"></Setter>
<Setter Property="Control.Margin" Value="10" ></Setter>
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Binding="{Binding ElementName=cb1,Path=IsChecked}" Value="True"></Condition>
<Condition Binding="{Binding ElementName=cb2,Path=IsChecked}" Value="True"></Condition>
</MultiDataTrigger.Conditions>
<MultiDataTrigger.Setters>
<Setter Property="Control.Background" Value="Red"></Setter>
</MultiDataTrigger.Setters>
</MultiDataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<Grid ShowGridLines="True">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<Button Grid.Row="0" Name="but" Style="{StaticResource buttonStyle}" Content="属性触发器"/>
<Button Grid.Row="1" Style="{StaticResource buttonStyle-Multi}" Content="多条件属性触发器"/>
<Button Grid.Row="2" Content="按钮" Style="{StaticResource buttonClickStyle}"></Button>
<TextBox Grid.Row="3" Margin="10" Style="{StaticResource DataTextTrigger}" Text="LightBlue"></TextBox>
<StackPanel Grid.Row="4" Name="panel1" Style="{StaticResource DataTextTrigger-Multi}">
<CheckBox Name="cb1" >全选后改变背景颜色</CheckBox>
<CheckBox Name="cb2" >全选后改变背景颜色</CheckBox>
</StackPanel>
</Grid>
</Window>

控件模板

在WPF中,每个控件都有一个默认的控件模板,用于定义控件的基本外观和行为。WPF使用ControlTemplate定义控件的外观,每个控件都有一个Template的属性。默认情况下。控件通过该属性获取呈现的外观,通过更改ControlTemplate,可以为控件定义一个新的样式

<Window x:Class="WPFDemo.TemplateDemo"
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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WPFDemo"
mc:Ignorable="d"
Title="TemplateDemo" Height="300" Width="300">
<Window.Resources>
<ControlTemplate x:Key="ButtomTemplate" TargetType="{x:Type Button}"> <Border Name="Border" BorderBrush="{TemplateBinding Foreground}"
BorderThickness="{TemplateBinding BorderThickness}"
CornerRadius="5" Background="{TemplateBinding Background}"
TextBlock.Foreground="{TemplateBinding Foreground}"
Margin="{TemplateBinding Margin}">
<ContentPresenter RecognizesAccessKey="True"
HorizontalAlignment="{TemplateBinding HorizontalAlignment}"
VerticalAlignment="{TemplateBinding VerticalAlignment}"> </ContentPresenter>
</Border>
<!--设置模板触发器-->
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter TargetName="Border" Property="Background" Value="Red"></Setter>
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter TargetName="Border" Property="Background" Value="Yellow"></Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Window.Resources>
<Grid> <Button Template="{StaticResource ButtomTemplate}" Margin="10" Background="LightBlue" Content="我是套用模板的button"></Button>
</Grid>
</Window>

最新文章

  1. flush和reflush
  2. 线段树 HDU 3397
  3. IIS发布WCF服务项目之本地
  4. 做NavMesh相关工作时收集的一些文章
  5. windows7使用Source insight上远程修改ubuntu共享内核源码
  6. JavaScript学习——内置属性
  7. 设置textview显示框内容不可编辑不可选择。
  8. ASP.NET 将DataTable解析成JSON简介
  9. WEB API 用MemoryStream流做下载功能
  10. 关于aspx 页面生成html 源码顶部空行不得不说的事儿
  11. iOS开发ARC入门和使用
  12. 字符串查找 cmd find命令
  13. 对java数组的一些理解
  14. Android开发过程中使用弱引用解决内存泄露的习惯
  15. 算法与数据结构(三) 二叉树的遍历及其线索化(Swift版)
  16. 【原创】运维基础之Docker(2)通过docker部署zookeeper nginx tomcat redis kibana/elasticsearch/logstash mysql kafka mesos/marathon
  17. nginx隐藏tp路由index.php
  18. java的post请求
  19. LR的损失函数&amp;为何使用-log损失函数而非平方损失函数
  20. 首先看一下友晶DE-SOC开发板的user manual

热门文章

  1. 数据转换失败 java.math.BigDecimal cannot be cast to java.lang.String
  2. Navicat 连接VMware中Ubuntu 下的mysql5.7遇到的坑
  3. js 实现数据结构 -- 链表
  4. 【LOJ6482】LJJ 爱数数 数论
  5. python 自动发现Java端口
  6. [File transfer]Syncthing
  7. request 获取body内容
  8. 【强大的PDF格式转换工具】Lighten PDF Converter OCR for Mac 6.2.0
  9. js重点--原型链继承详解
  10. Hibernate日志输出到SLF4J