目前.Net Core 3.1已经发布一段时间了, 对WPF的支持已经日渐完善。还记得当时微软在Github放出WPF源码时,.Net Core的版本应该是1.0吧,我以为WPF可以跨平台了,结果还是不支持跨平台。
在以后的博客示例程序中,我都会使用.Net Core来构建 WPF App,用法与.Net Framework基本一致。
以前在设置控件样式或自定义控件时,都是使用触发器来进行样式更改。触发器可以在属性值发生更改时启动操作。
像这样:
<Style TargetType="ListBoxItem"> <Setter Property="Opacity" Value="0.5" /> <Setter Property="MaxHeight" Value="75" /> <Style.Triggers> <Trigger Property="IsSelected" Value="True"> <Trigger.Setters> <Setter Property="Opacity" Value="1.0" /> </Trigger.Setters> </Trigger> </Style.Triggers>
</Style>
还可以使用VisualState类来进行样式更改
VisualState类实现了可以让控件始终处于特定的状态,例如,当鼠标在控件的表面上移动时,该控件被视为处于MouseOver状态
。 没有特定状态的控件被视为处于公用 Normal
状态。
状态分为多个组,前面提到的状态属于 CommonStates
状态组(VisualStateGroup)。 大多数控件都有两个状态组:CommonStates
和 FocusStates
。
在应用于控件的每个状态组中,控件始终处于每个组的一种状态。但是,控件不能处于同一组中的两种不同状态。
完整的状态可以参照下表:
VisualState 名称 | VisualStateGroup 名称 | 描述 |
---|---|---|
Normal | CommonStates | 默认状态。 |
MouseOver | CommonStates | 鼠标指针悬停在控件上方。 |
Pressed | CommonStates | 已按下控件。 |
Disabled | CommonStates | 已禁用控件。 |
Focused | FocusStates | 控件有焦点。 |
Unfocused | FocusStates | 控件没有焦点。 |
下面我们使用VisualState类来自定义一个Button样式
1、使用Visual Studio 2019创建一个.Net Core WPF程序
2、在MainWindow中添加一个Button控件
1 <Window x:Class="VisualStateDemo.MainWindow" 2 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 3 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 4 xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 5 xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 6 xmlns:local="clr-namespace:VisualStateDemo" 7 mc:Ignorable="d" 8 Title="MainWindow" Height="450" Width="800"> 9 <Grid> 10 <Button Content="Test" HorizontalAlignment="Center" VerticalAlignment="Center" Width="88" Height="26"/> 11 </Grid> 12 </Window>
3、在Windows.Resources下定义样式,如下
1 <Window.Resources> 2 <Style TargetType="{x:Type Button}"> 3 <Setter Property="BorderBrush" Value="Transparent"/> 4 <Setter Property="Background" Value="Black"/> 5 <Setter Property="Foreground" Value="White"/> 6 7 <Setter Property="Template"> 8 <Setter.Value> 9 <ControlTemplate TargetType="{x:Type Button}"> 10 <Border BorderThickness="{TemplateBinding Border.BorderThickness}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="border" SnapsToDevicePixels="True" CornerRadius="5"> 11 <VisualStateManager.VisualStateGroups> 12 <VisualStateGroup Name="CommonStates"> 13 <VisualState Name="Normal"> 14 <Storyboard> 15 <ColorAnimation Storyboard.TargetName="border" 16 Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 17 To="{TemplateBinding Background}" 18 Duration="0:0:0.3"/> 19 </Storyboard> 20 </VisualState> 21 <VisualState Name="MouseOver"> 22 <Storyboard> 23 <ColorAnimation Storyboard.TargetName="border" 24 Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" 25 To="Silver" 26 Duration="0:0:0.3"/> 27 </Storyboard> 28 </VisualState> 29 <VisualState Name="Pressed"> 30 <Storyboard> 31 <ColorAnimation Storyboard.TargetName="border" Storyboard.TargetProperty="(Border.Background).(SolidColorBrush.Color)" To="#7b8488" Duration="0:0:0.3"/> 32 </Storyboard> 33 </VisualState> 34 </VisualStateGroup> 35 </VisualStateManager.VisualStateGroups> 36 <ContentPresenter RecognizesAccessKey="True" Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" Name="contentPresenter" Margin="{TemplateBinding Control.Padding}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding UIElement.SnapsToDevicePixels}" Focusable="False" /> 37 </Border> 38 </ControlTemplate> 39 </Setter.Value> 40 </Setter> 41 </Style> 42 </Window.Resources>
4、运行效果如下:
Normal