I have four visual states defined each affecting different child controls within the same silver-light control. Is it possible for me to create other visual states which invoke a combination of these others?
So if I have Visual_Group_1, Visual_Group_2, Visual_Group_3, Visual_Group_4
I'm happy to implement a solution in xaml or codebehind or a combination of both
.
The alternative I'm looking at currently involves tonnes of code copy+paste and I'm not too keen to do that.
Some more detail per request:
This is what I roughly have right now:
<VisualState x:Name="State1">
<ColorAnimation Storyboard.TargetName="Path1"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="Blue" Duration="0:0:0.5" />
// fade out the rest of the paths...
<ColorAnimation Storyboard.TargetName="Path2"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:0.5" />
<ColorAnimation Storyboard.TargetName="Path3"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:0.5" />
<ColorAnimation Storyboard.TargetName="Path4"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:0.5" />
</VisualState>
<VisualState x:Name="State2">
<ColorAnimation Storyboard.TargetName="Path3"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="Red" Duration="0:0:0.5" />
// fade out the rest of the paths...
<ColorAnimation Storyboard.TargetName="Path2"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:0.5" />
<ColorAnimation Storyboard.TargetName="Path1"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:0.5" />
<ColorAnimation Storyboard.TargetName="Path4"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:0.5" />
</VisualState>
<VisualState x:Name="State3">
<ColorAnimation Storyboard.TargetName="Path4"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="Pink" Duration="0:0:0.5" />
// fade out the rest of the paths...
<ColorAnimation Storyboard.TargetName="Path2"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:0.5" />
<ColorAnimation Storyboard.TargetName="Path1"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:0.5" />
<ColorAnimation Storyboard.TargetName="Path3"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000" Duration="0:0:0.5" />
</VisualState>
My objective is to have a control which when you click on cycles from state1 to state3, each state fades in a different path while fading out the other paths. My problem is that there is a tonne of copy+paste in the 'fade out the rest of the paths' section, so if I wanted to add a Path5 it would mean adding it to every single visual state already defined, or if I wanted to change the fadeoff colour or animation I would have to do it to every visual state.
Thanks for providing the XAML. This is how I would tackle the problem.
First off, create the VisualStates
individually for each Path
. (I would recommend using a Style
instead to save you re-coding a very similar VisualState
into each Path, but I'm not familiar enough with them to know if you can apply different colours to each.)
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="Path1States">
<VisualState x:Name="Activate">
<Storyboard>
<ColorAnimation Storyboard.TargetName="Path1"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="Blue"
Duration="0:0:0.5" />
</Storyboard>
</VisualState>
<VisualState x:Name="Deactivate">
<Storyboard>
<ColorAnimation Storyboard.TargetName="Path1"
Storyboard.TargetProperty="(Path.Fill).(SolidColorBrush.Color)"
To="#00000000"
Duration="0:0:0.5" />
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="Path2States">
<!-- ... etc ... -->
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
Now, create a List
in the code-behind that contains each of the related objects, and then right your own GoToState
function such that it turns on the in state for one object, and calls the off state for the rest.
List<Path> pathList;
public Page() // constructor
{
InitializeComponent();
pathList = new List<Path>();
pathList.Add(Path1);
// and so forth
}
// Call this function when you want to change the state
private void ActivatePath(Path p)
{
foreach (Path listItem in pathList)
{
// If the item from the list is the one you want to activate...
if (listItem == p)
VisualStateManager.GoToState(listItem, "Activate", true);
// otherwise...
else
VisualStateManager.GoToState(listItem, "Deactivate", true);
}
}
If I were better at XAML and styling I might have a cleaner way of creating the VisualStates. However, my forte is more on the logic and coding side. That being said, it's much cleaner that writing out the same VisualState
four or five times! :)
Hope this helps!