问题描述
当依赖项属性Message
为NULL或填充时,为什么我的视觉状态不起作用?
WPF代码:
<Window x:Class="VisualStateTest.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:VisualStateTest"
mc:Ignorable="d"
Title="MainWindow" Height="450" Width="800">
<Border x:Name="border" Background="Black">
<visualstatemanager.VisualStateGroups>
<VisualStateGroup x:Name="LocationErrorStatusVisualStateGroup">
<VisualState x:Name="DefaultVisualState">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Image.source)" Storyboard.TargetName="myImage">
<discreteObjectKeyFrame KeyTime="0">
<discreteObjectKeyFrame.Value>
<BitmapImage UriSource="/VisualStateTest;component/Resources/Empty.png"/>
</discreteObjectKeyFrame.Value>
</discreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="MessageVisualState">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Image.source)" Storyboard.TargetName="myImage">
<discreteObjectKeyFrame KeyTime="0">
<discreteObjectKeyFrame.Value>
<BitmapImage UriSource="/VisualStateTest;component/Resources/Message.png"/>
</discreteObjectKeyFrame.Value>
</discreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</visualstatemanager.VisualStateGroups>
<Image x:Name="myImage"/>
</Border>
</Window>
后面的C#代码:
using System.Windows;
namespace VisualStateTest
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
#region Message
/// <summary>
/// Message Dependency Property
/// </summary>
public static readonly DependencyProperty MessageProperty =
DependencyProperty.Register("Message",typeof(string),typeof(MainWindow),new FrameworkPropertyMetadata(null,new PropertyChangedCallback(OnMessageChanged)));
/// <summary>
/// Gets or sets the Message property. This dependency property
/// indicates the message.
/// </summary>
public string Message
{
get { return (string)GetValue(MessageProperty); }
set { SetValue(MessageProperty,value); }
}
/// <summary>
/// Handles changes to the Message property.
/// </summary>
private static void OnMessageChanged(DependencyObject d,DependencyPropertyChangedEventArgs e)
{
MainWindow target = (MainWindow)d;
string oldMessage = (string)e.OldValue;
string newMessage = target.Message;
target.OnMessageChanged(oldMessage,newMessage);
}
/// <summary>
/// Provides derived classes an opportunity to handle changes to the Message property.
/// </summary>
protected virtual void OnMessageChanged(string oldMessage,string newMessage)
{
if (newMessage == oldMessage)
return;
if (string.IsNullOrEmpty(newMessage))
{
visualstatemanager.GoToState(this,"DefaultVisualState",true);
}
else
{
visualstatemanager.GoToState(this,"MessageVisualState",true);
}
}
#endregion
public MainWindow()
{
Message = "test";
InitializeComponent();
}
}
}
解决方法
图像的构建动作应设置为Resource
。然后应使用Pack URIs引用图像,该图像应为
pack://application:,/Resources/Empty.png
pack://application:,/Resources/Message.png
有两种使用VisualStateManager
的方法。视觉状态可以定义:
- 在控件模板中,或
- 直接在控件中(如您在此处所做的操作)
如果未在模板中定义视觉状态,则必须调用GoToElementState
方法而不是GoToState
方法。
此外,您必须在实际上定义了相应视觉状态的控件上调用GoToElementState
方法,因此您需要在Border
而不是MainWindow
上调用
VisualStateManager.GoToElementState(border,"DefaultVisualState",true);
See here有关VisualStateManager