当我们需要设计出效果和样式更复杂的控件时,或一个样式的控件会在多处重复使用,亦可在修改其部分特征时使用控件模板是更好的设计和组织样式的办法。
样式设置和模板化是指一套功能,其中样式Style是一种将一组特征属性值应用到多个元素的方法,用于设置控件的外观属性,比如:长、宽、颜色等。
控件模板 Control template 是一种定义控件的外观和结构的方法,用于重写自定义控件的视觉行为,比如:形状、事件、触发器和动画等。
1. Window Resources
资源的声明和使用
每个WPF的界面元素都具有Resources属性,这个属性的类型为ResourcesDictionary类型,其能够以键值对的形式存储资源,当我们需要某个资源时,使用键值对可以索引到资源对象。我们可以在任何元素上去定义资源,可通过x:Ke指令来分配唯一键。
<Window.Resources>
<SolidColorBrush x:Key="MyC" Color="LightPink"/>
<SolidColorBrush x:Key="MyB" Color="HotPink"/>
</Window.Resources>
<Border Grid.Column="1" CornerRadius="0,10,10,0" Background="{StaticResource MyB}"/></pre>
最常见方便的是在根元素上定义资源,在根元素上定义资源的好处是:
- 让资源在逻辑树上的所有子元素中共享,提高资源的复用性和一致性。
- 减少资源字典中的数量和嵌套层次,简化资源的管理和维护。
- 提高资源的加载和查询效率,避免不必要的性能开销。
- 方便地使用系统资源或主题资源,实现界面的动态适应。
静态和动态资源
静态资源使用(StaticResources)指的是在程序载入内存时,对资源的一次性使用,之后就不再去访问这个资源了;
动态资源使用(DynamicResources)指的是在程序运行过程中,仍然会去访问该资源。
<pre class="wp-block-syntaxhighlighter-code"> <Window.Resources>
<SolidColorBrush x:Key="MyC" Color="LightPink"/>
<SolidColorBrush x:Key="MyB" Color="HotPink"/>
</Window.Resources>
<Border Grid.Column="1" CornerRadius="0,10,10,0" Background="{DynamicResource MyB}"/>
<Button Click="Button_Click_2" Width="200" Height="50">点击换色2</Button>
private void Button_Click_2(object sender, RoutedEventArgs e)
{
this.Resources["MyB"] = new SolidColorBrush((Color)ColorConverter.ConvertFromString("#878787"));
}</pre>
在WPF项目中,我们一般有以下几种方法来管理Window.Resources:
- 直接在窗口对应的Xaml中定义资源,这样可以方便地在主窗口中使用资源,但是如果资源很多或者需要在其他窗口或用户控件中使用,就不太好用。
- 在App.xaml中定义资源,这样可以让资源在整个应用程序的范围内共享,实现一致的主题和外观,但是如果资源很多或者需要根据不同的窗口或用户控件进行区分,就不太好用。
- 建文件夹并建内容元素为ResourceDictionary的xaml页面,这样可以将资源分组和模块化,方便管理和维护,也可以根据需要在不同的窗口中或用户控件引用或并资源。
2. Style
样式资源
样式是一种将一组特征属性值应用到多个元素的方法,用于设置控件的外观属性如长宽、颜色、字体、大小等。
WPF中的各类控件元素,都可以自由设置其样式。
在设定Style时,我们需要使用X:Key声明键名,并设置目标类型TargetType,使用x:Type将类型传入。
在Style标签的内容区通过Setter标签,设置Property属性和属性值Value。
<pre class="wp-block-syntaxhighlighter-code"> <Style x:Key="TextStyle" TargetType="{x:Type TextBlock}">
<Setter Property="FontSize" Value="32"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="TextAlignment" Value="Center"/>
<Setter Property="FontWeight" Value="Bold"/>
</Style>
<TextBlock Text="Sigin In To App"
Foreground="#0072c0"
Margin="0,100,0,25"
Style="{StaticResource TextStyle}"/></pre>
3. Control Template
WPF的ControlTemplate是一种用于定义和自定义控件的外观和结构的模板,它可以完全替换控件的默认模板,实现个性化和复杂的效果。
WPF的ControlTemplate有以下几个特点:
- ControlTemplate是一个XAML元素,它可以包含任何类型的UI元素,如布局、形状、图像、文本等,这些元素构成了控件的视觉树(VisualTree)
- ControlTemplate可以使用TemplateBinding或Binding来绑定控件的属性或数据,从而实现动态的显示和更新。
- ControlTemplate可以使用Tiggers来定义控件对不同的条件或事件的响应,如:改变属性、播放动画、执行操作等。
- ControlTemplate可以使用ContentPresenter或ItemsPresenter来呈现控件的内容或子元素,从而保留控件的基本功能。
- ControlTemplate可以在Style或ResourceDictionary中定义,并应用到一个或多个控件上,从而实现资源的重用和管理。
<pre class="wp-block-syntaxhighlighter-code"> <Style x:Key="buttonman" TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="16"/>
<Setter Property="FontFamily" Value="Arial"/>
<Setter Property="Width" Value="170"/>
<Setter Property="Background" Value="Transparent"/>
<Setter Property="Foreground" Value="White"/>
<Setter Property="BorderBrush" Value="White"/>
<Setter Property="Content" Value="Sign Up"/>
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Border Background="{TemplateBinding Background}"
CornerRadius="22"
BorderThickness="3"
BorderBrush="{TemplateBinding BorderBrush}"
Padding="10">
<ContentPresenter HorizontalAlignment="Center"
VerticalAlignment="Center"/>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Button Content="Sign Up"
Margin="0,130,0,0"
Style="{StaticResource buttonman}"
/></pre>
4. Tigger触发器
WPF的Tigger是一种用于定义和管理XAML资源的触发器,它可以根据不同的条件或事件来改变控件的属性或行为。
以下是触发器的类型:
- 基本触发器(Tigger):这种触发器是根据控件自身的依赖属性的值来触发的,例如:当鼠标移动到按钮上时,改变按钮的背景色。
- 数据触发器(DataTrigger):这种触发器是根据绑定的数据的值来触发的,例如:当绑定的数据为真时,显示一个图标。
- 事件触发器(EventTrigger):这种触发器是根据控件的路由事件来触发的,例如:当按钮被点击时,播放一个动画。
- 多条件触发器(MultTrigger、MultiDataTrigger):这种触发器是根据多个条件的组合来触发的,例如:当控件的属性和绑定的数据同时满足某些值时,改变控件的样式。
<pre class="wp-block-syntaxhighlighter-code"> <Style.Triggers>
<!--hover-->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Background" Value="White"/>
<Setter Property="Foreground" Value="Blue"/>
</Trigger>
<!--click-->
<Trigger Property="IsMouseCaptured" Value="True">
<Setter Property="Background" Value="Blue"/>
<Setter Property="Foreground" Value="White"/>
</Trigger>
</Style.Triggers></pre>