Reputation: 217
Why do my visual states not work when the dependency property Message
is NULL or filled ?
WPF code:
<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# code behind:
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();
}
}
}
Upvotes: 1
Views: 187
Reputation: 759
The build action of the images should be set to Resource
. The images should then be referenced using Pack URIs which would be
pack://application:,,,/Resources/Empty.png
pack://application:,,,/Resources/Message.png
There are two ways to use the VisualStateManager
. The visual states can be defined:
When the visual states are not defined within a template, you have to call the GoToElementState
method rather than the GoToState
method.
Also, you have to call the GoToElementState
method on the control that actually defines the corresponding visual states, so you need to call it on the Border
and not on the MainWindow
VisualStateManager.GoToElementState(border, "DefaultVisualState", true);
See here for more details on the VisualStateManager
Upvotes: 0