wpf入门第四篇 VisualState
前言
本文是wpf入门系列第四篇,面向有winform或者web前端基础的、并且也有C#基础的同学。
在WPF中,View(Window,UserControl等)常常会根据不同的状态来显示不同的内容,比如消息的未读和已读是两种状态,这两种状态下View的表现形式会有所差别。本文将从头开始一个的示例项目,来简单的介绍VisualState的用法。
本文使用了 Visual Studio 2017 进行演示讲解。
wpf入门系列导航页面: https://blog.****.net/wf824284257/article/details/88757497
上一步: wpf入门第三篇 ControlTemplate、Trigger与Storyboard
https://blog.****.net/wf824284257/article/details/88783979
开始
打开 VS2017,新建WPF项目,命名为 WpfVisualStateTest ,点击确定。
向项目中添加一个用户控件. 右键点击项目名,选择【添加】->【用户控件】,命名为Msg 。
将Msg.xaml 代码替换为如下代码:
<UserControl x:Class="WpfVisualStateTest.Msg"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:WpfVisualStateTest"
mc:Ignorable="d"
d:DesignHeight="450" d:DesignWidth="800" Height="80">
<Border Name="bdMain" CornerRadius="10" Background="White" BorderBrush="#333" BorderThickness="1" Margin="10"
MouseLeftButtonDown="Border_MouseLeftButtonDown" >
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="StateRead">
<VisualState x:Name="HasRead">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="bdMain"
Storyboard.TargetProperty="Opacity"
To="0.1"
Duration="0:0:1"></DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid Name="gdMain" >
<Grid.RowDefinitions>
<RowDefinition Name="rowTitle"></RowDefinition>
<RowDefinition Name="rowBody"></RowDefinition>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Name="tTitle" VerticalAlignment="Center" Margin="10,0,0,0"
FontSize="20" Foreground="Black" Text="{Binding Title}"></TextBlock>
<TextBlock Grid.Row="1" Name="tBody" VerticalAlignment="Center" Margin="10,0,0,0"
FontSize="15" Foreground="#888" Text="{Binding Body}"></TextBlock>
</Grid>
</Border>
</UserControl>
根据代码可以看出,我们在Msg用户控件中添加了两行,第一行是比较显眼的TItle,第二行是弱一点的Body. 两个TextBlock的Text属性都使用了Binding。 现在我们需要一个VierModel来驱动我们的View。
向项目中添加一个VM_Msg类,并将代码替换为下面代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace WpfVisualStateTest
{
public class VM_Msg
{
public string Title { get; set; }
public string Body { get; set; }
}
}
打开 Msg.xaml.cs ,使用下面的代码来替换原本内容。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfVisualStateTest
{
/// <summary>
/// Msg.xaml 的交互逻辑
/// </summary>
public partial class Msg : UserControl
{
public Msg(VM_Msg vm)
{
InitializeComponent();
this.DataContext = vm;
}
private void Border_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
VisualStateManager.GoToState(this, "HasRead", false);
}
}
}
Border_MouseLeftButtonDown 中写了改变控件状态的代码。下面我们来试运行一下,看看是否可以达到我们的预期效果。
打开MainWindow.xaml,将代码替换为如下代码:
<Window x:Class="WpfVisualStateTest.MainWindow"
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:WpfVisualStateTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Grid>
<StackPanel Name="spList" Orientation="Vertical">
</StackPanel>
</Grid>
</Window>
打开MainWindow.xaml.cs ,将代码替换为如下代码:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfVisualStateTest
{
/// <summary>
/// MainWindow.xaml 的交互逻辑
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
VM_Msg vm = new VM_Msg()
{
Title = "WPF的VisualState",
Body = "在WPF中,View(Window,UserControl等)常常会根据不同的状态来显示不同的内容"
};
Msg msg = new Msg(vm);
spList.Children.Add(msg);
}
}
}
F5 运行项目,点击Msg控件,可以看到它逐渐变得透明。
我们新加一个State,使得Msg重新回到原来的状态,并为Msg的Border添加一个右键点击事件来进入这个状态。
将Msg.xaml的 Border及VisualStateManager 代码改为如下代码:
<Border Name="bdMain" CornerRadius="10" Background="White" BorderBrush="#333" BorderThickness="1" Margin="10"
MouseLeftButtonDown="Border_MouseLeftButtonDown" MouseRightButtonDown="BdMain_MouseRightButtonDown">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="StateRead">
<VisualState x:Name="HasRead">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="bdMain"
Storyboard.TargetProperty="Opacity"
To="0.1"
Duration="0:0:1"></DoubleAnimation>
</Storyboard>
</VisualState>
<VisualState x:Name="NotRead">
<Storyboard>
<DoubleAnimation
Storyboard.TargetName="bdMain"
Storyboard.TargetProperty="Opacity"
To="1"
Duration="0:0:1"></DoubleAnimation>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
在Msg.xaml.cs中添加右键点击事件
private void BdMain_MouseRightButtonDown(object sender, MouseButtonEventArgs e)
{
VisualStateManager.GoToState(this, "NotRead", false);
}
F5 运行项目,左键点击Msg控件后它将逐渐变得透明,之后右键点击Msg控件后它将逐渐恢复。
结束
本文通过一个小的测试项目来简单说明了 WPF 中 VisualState 的用法。若有其他需要可留言,24小时内回复。
本文所用代码示例可以在博主的资源页下载: https://download.****.net/download/wf824284257/11084852
若有不足请指正,感谢。