Is it possible to have nested visual states. What I mean is if a ParentControl has a ChildControl and both have their own visual states, is it possible by setting the state of the ParentControl to change the state of the ChildControl accordingly.
You need to call the GoToState
method to change the visual state of the child control.
Since you need to call a method you can't use Storyboards in visual state manager of a parent control since these can only animate properties.
Hence you need to write some code in the child control. To monitor the state of the parent and respond appropriately.
There are a number of different ways to do this but the crucial nugget of info is to use the VisualStateManager.GetVisualStateGroups
method to find the VisualStateGroup
on the parent that you are interested in, then attach to that group's CurrentStateChanging
event. Hence code in the Child control can be notified when a state its interested in is being transitioned to by the parent and can call GoToState
appropriately against itself.
I'm just going to declare a new dependency property:
public static readonly DependencyProperty StateProperty =
DependencyProperty.Register("State",
typeof( string ),
typeof( TextBlockControl ),
new PropertyMetadata("Top",
new PropertyChangedCallback(StateChanged)));
[Category("DigItOut"), Description("State")]
public string State
{
get
{
return this.GetValue(StateProperty).ToString();
}
set
{
this.SetValue(StateProperty, value);
}
}
private static void StateChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
{
if (!String.IsNullOrEmpty(args.NewValue.ToString()))
VisualStateManager.GoToState(sender as TextBlockControl, args.NewValue.ToString(), true);
}
And then just set it from it's parents state:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="States">
<VisualState x:Name="Reverse">
<Storyboard>
<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="textBlockControl" Storyboard.TargetProperty="(TextBlockControl.State)">
<DiscreteObjectKeyFrame KeyTime="00:00:00">
<DiscreteObjectKeyFrame.Value>
<System:String>Bottom</System:String>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Straight"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
But if I still want control over the use of transitions, then I'll have to find another solution. Probably second property.