对象资源
资源集合
资源被存储在Resouces属性中,这是一个键值对的集合类型,实例化位ResourceDictionary对象。为了定义资源,必须要通过x:key属性来为资源分配一个键。在同一资源集合中,键名称必须唯一。在使用资源时,会先从元素树所引用的资源集合中向上找,直到找到Key为止。
代码示例:
<Window.Resources>
<ImageBrush x:Key="TileBrush" TileMode="Tile" ViewportUnits="Absolute" Viewport="0 0 32 32" ImageSource=".\image\About.bmp" Opacity="0.3"></ImageBrush>
</Window.Resources>
<Grid>
<TextBox HorizontalAlignment="Left" Height="23" Margin="140,251,0,0" TextWrapping="Wrap" Text="TextBox" VerticalAlignment="Top" Width="120" Background="{StaticResource TileBrush}"/>
<Button Content="Button" HorizontalAlignment="Left" Margin="149,160,0,0" VerticalAlignment="Top" Width="75" >
<Button.Background>
<StaticResource ResourceKey="TileBrush"></StaticResource>
</Button.Background>
</Button>
</Grid>
StaticResource为静态资源,一旦创建不会被改变,注意在引用静态资源之前先定义资源,否则会抛出异常。
系统资源
所谓系统资源,是指一些系统的设置环境信息,应用程序可能需要获取这些信息,比如SystemColors\SystemFonts和SystemParameters,这3类都位于System.Windows命名空间,这3个类提供了大量的静态属性来返回系统的颜色、字体和字体参数信息。如果要使用这些系统信息可以使用X:Static标记扩展。
比如获取SystemColors中的颜色来设置TextBlock的前景色,FontSize字体信息。
<TextBlock HorizontalAlignment="Left" Margin="86,176,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Foreground="{x:Static SystemColors.WindowTextBrush}" FontSize="{x:Static SystemFonts.IconFontSize}" />
存在的问题:
当系统设置发生变化时,以及当系统字体和系统颜色发生改变时,使用X:Static标记扩展引用的系统信息不会被自动更新。此时,可以借助于动态资源的形式在系统信息被更改后来自动的更新程序。这些键对象的命名是在属性的名称后面加一个Key字符串。
例如将上式代码改为如下:
<TextBlock HorizontalAlignment="Left" Margin="86,176,0,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" Foreground="{DynamicResource {x:Static SystemColors.WindowTextBrushKey}}" />
样式
Style最重要的种属性的Setter和Trigger,Setter类帮助我们设置控件的静态外观风格,Trigger类则帮助我们设置控件的行为风格。
style中的Setter
创建一个简单的样式
<Window.Resources>
<Style x:Key="BigFont">
<Setter Property="Control.FontFamily" Value="Times New Roman"/>
<Setter Property="Control.FontSize" Value="26"/>
<Setter Property="Control.Margin" Value="6"/>
</Style>
</Window.Resources>
<Grid>
<Button Content="an1" HorizontalAlignment="Left" Margin="115,105,0,0" VerticalAlignment="Top" Width="75" Style="{StaticResource BigFont}"/>
<Button Content="an2" HorizontalAlignment="Left" Margin="115,162,0,0" VerticalAlignment="Top" Width="75" Style="{StaticResource BigFont}"/>
<Button Content="an3" HorizontalAlignment="Left" Margin="115,236,0,0" VerticalAlignment="Top" Width="75" Style="{StaticResource BigFont}"/>
</Grid>
WPF中的样式声明由Style对象构成,该对象包含一个或多个Setter对象组成的集合。每个Setter都包含一个Property和一个Value,value表示属性值将样式声明为资源后,就 可以像引用任何其他资源一样引用样式。
2019年12/10补充:在资源列表中如果不设置x:Key值,则在再资源集合有效范围内的所有可视化对象都会自动套用资源中的样式。Style对象通过TargetType属性指定该样式针对那个类型,如“TargetType=“{x:Type TextBlock}””
注意元素本身的属性优先级最高。
内联样式的创建
<Button Content="an1" HorizontalAlignment="Left" Margin="115,105,0,0" VerticalAlignment="Top" Width="75" >
<Button.Style>
<Style>
<Setter Property="Control.FontFamily" Value="Times New Roman"/>
<Setter Property="Control.FontSize" Value="26"/>
<Setter Property="Control.Margin" Value="6"/>
</Style>
</Button.Style>
</Button>
在样式中设置属性
如果需要在Setter中设置多个属性,如下
<Grid>
<Button Content="an1" HorizontalAlignment="Left" Margin="115,105,0,0" VerticalAlignment="Top" Width="75" >
<Button.Style>
<Style>
<Setter Property="Control.FontFamily" Value="Times New Roman"/>
<Setter Property="Control.FontSize" Value="26"/>
<Setter Property="Control.Margin" Value="6"/>
<Setter Property="Button.Background">
<Setter.Value>
<LinearGradientBrush StartPoint="1,0" EndPoint="1,1">
<LinearGradientBrush.GradientStops>
<GradientStop Color="Blue" Offset="1"></GradientStop>
<GradientStop Color="White" Offset="0"></GradientStop>
</LinearGradientBrush.GradientStops>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Style>
</Button.Style>
</Button>
<!--<Button Content="an2" HorizontalAlignment="Left" Margin="115,162,0,0" VerticalAlignment="Top" Width="75" Style="{StaticResource BigFont}"/>
<Button Content="an3" HorizontalAlignment="Left" Margin="115,236,0,0" VerticalAlignment="Top" Width="75" Style="{StaticResource BigFont}"/>-->
</Grid>
渐变色
根据指定的类型自动应用样式
<Window.Resources>
<Style TargetType="{x:Type Button}">
<Setter Property="Control.FontFamily" Value="Times New Roman"/>
<Setter Property="Control.FontSize" Value="26"/>
<Setter Property="Control.Margin" Value="6"/>
</Style>
</Window.Resources>
使用 TargetType属性指定样式将应用到的类型,具有该类型的控件将自动的应用样式。
style中的Trigger
Trigger触发器,即当某些条件满足时会触发一个行为,包括事件触发型EvenTrigger,数据变化触发型Trigger/DataTrigger,多条件触发型MultiTrigger/MultiDataTrigger。
- 基本的Trigger
Trigger有property和Value两个属性,Trigger关注的是属性名称,Value是触发条件。它还有一组Setter属性,一旦触发条件满足,这组Setter的“属性-值”就会被应用。
<Style Target="CheckBox">
<Style.Trigger>
<Trigger Property="IsChecked" Value="true">
<Trigger.Setter>
<Setter Property="FontSize" Value="20"/>
</Trigger.Setter>
</Style.Trigger>
</Style>
- MultiTrigger
多个条件是触发
举例
<Style Target="CheckBox">
<Style.Trigger>
<MultiTrigger.Condition>
<Condition Property="IsChecked" Value="true"/>
<Condition Property="Content" Value="另外一个条件"/>
</MultiTrigger.Condition>
<MultiTrigger.Setter>
<Setter Property="FontSize" Value="20"/>
<MultiTrigger.Setter>
</Style.Trigger>
</Style>
绑定事件处理程序
Style类提供了EventSetter元素,使开发人员可以在样式中定义事件处理器。比如,如果想为多个元素使用相同的事件处理器,则可以在样式中预先进行定义。
<Window.Resources>
<Style x:Key="MouseEventHightligntStyle">
<!-- 定义鼠标进入按钮时的事件处理器 -->
<EventSetter Event="Button.MouseEnter" Handler="ButtonMouseEnter"/>
<!-- 定义鼠标移除按钮时的事件处理器 -->
<EventSetter Event="Button.MouseLeave" Handler="ButtonMouseLeave"/>
<Setter Property="Control.FontSize" Value="26"/>
<Setter Property="Control.Margin" Value="6"/>
</Style>
</Window.Resources>
<Grid>
<Button Content="an2" HorizontalAlignment="Left" Margin="115,162,0,0" VerticalAlignment="Top" Width="75" Style="{StaticResource MouseEventHightligntStyle}"/>
<Button Content="an3" HorizontalAlignment="Left" Margin="115,236,0,0" VerticalAlignment="Top" Width="75" Style="{StaticResource MouseEventHightligntStyle}"/>
</Grid>
EventSetter的Event用于指定事件名称,需要使用空间名称再加上事件名称进行定义。Handler用于指定事件处理器。
void ButtonMouseEnter(object sender, MouseEventArgs e)
{
((Button)sender).Foreground = new SolidColorBrush(Colors.Blue);
}
void ButtonMouseLeave(object sender, MouseEventArgs e)
{
((Button)sender).Foreground = new SolidColorBrush(Colors.Black);
}
2021/6/13补充
【摘自深入浅出话资源】
每个WPF的界面元素都具有一个名为Resource的属性,其类型为ResourceDictionary,它视资源对象为object类型,所以在使用资源时先要对资源进行类型转换,XAML编译器能够根据标签的Attribute自动识别资源类型。
动态资源(DynamicResource)使用指的是在程序运行过程中仍能去访问资源。
静态资源(StaticResource)指的是程序载入内存时对资源的一次性使用。
程序中的二进制资源
如果要添加的资源时字符串而非文件,我们可以使用应用程序Properties名称空间中Resources.resx资源文件,为了能够使用它,需要把它的访问级别由Internal改为public。
在 XAML代码中使用Resources.resx资源需要做如下修改
xmlns:prop="clr-namespace:WPF_Study.Properties"
<TextBlock Text="{x:Static prop:Resources.UseName}"/>
总结:使用Resource.rexs最大的好处就是便于程序的国际化,本地化。