Change Visual State On PropertyChanged - wpf

Is it possible to add a behaviour in Blend to switch to a different visual state in response to a property changed event on a binding? It would need to switch to this state for a few seconds and then back out.
I'm trying to change the background colour of a control everytime a count value on the datacoontext changes. I've tried using a GoToStateAction and EventTrigger/DataTrigger but can't quite get the trigger setup right - I suspect that I need to approach this in a different way but I'm not sure how.
Any help would be appreciated -
Here is the xaml for the border - I'm stuck on how to set up the trigger to change the visual state - I want to switch to BrightState for a few seconds and back to NormalState everytime the Value of Count on the viewmodel changes
<Border x:Name="border" Grid.Row="2" Background="CadetBlue">
<StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
<TextBlock><Run Text="Count:"/></TextBlock>
<TextBlock x:Name="textBlock" Text="{Binding Count}" MinWidth="30">
<i:Interaction.Triggers>
<!--<i:EventTrigger EventName="MouseLeftButtonDown" SourceName="textBlock">
<ei:GoToStateAction/>
</i:EventTrigger>-->
</i:Interaction.Triggers>
</TextBlock>
</StackPanel>
</Border>
Here are the visual states defined to change the background colour of the border:
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="FlickerStateGroup">
<VisualState x:Name="NormalState"/>
<VisualState x:Name="BrightState">
<Storyboard>
<ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="border">
<EasingColorKeyFrame KeyTime="0" Value="#FF6CD9DC"/>
</ColorAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>

Related

VS2012 Setup like WPF window animated SizeToContent

I'm trying to achieve the same animation than VS2012 setup window, autosizing and centering on every content size change in a nice animated way.
The problem is that it can't be done purely by code as I don't know the final window size (for what I rely on SizeToContent="WidthAndHeight"), but letting SizeToContent="WidthAndHeight" by it's own does not allow me to animate the transition
Is there any way to do it?
I think the simplest way to achieve this is to use custom visual states within your window class. I made a small test project that you can download here: https://dl.dropboxusercontent.com/u/14810011/ResizingWindow.zip
You need Visual Studio 2012 to execute it.
The Main Window XAML looks like this:
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ResizingWindow"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
x:Name="Window" x:Class="ResizingWindow.MainWindow"
Title="MainWindow" Width="350" Height="300" WindowStyle="None" ResizeMode="NoResize" WindowStartupLocation="CenterScreen">
<Window.DataContext>
<local:MainWindowViewModel />
</Window.DataContext>
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="ExtendedStates">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0:0:0.6">
<VisualTransition.GeneratedEasingFunction>
<CubicEase EasingMode="EaseOut"/>
</VisualTransition.GeneratedEasingFunction>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Normal">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="TextBlock">
<EasingDoubleKeyFrame KeyTime="0" Value="0"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="Window">
<EasingDoubleKeyFrame KeyTime="0" Value="300"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
<VisualState x:Name="Extended">
<Storyboard>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)" Storyboard.TargetName="Window">
<EasingDoubleKeyFrame KeyTime="0" Value="400"/>
</DoubleAnimationUsingKeyFrames>
<DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)" Storyboard.TargetName="TextBlock">
<EasingDoubleKeyFrame KeyTime="0" Value="1"/>
</DoubleAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Grid.RowDefinitions>
<RowDefinition Height="300"/>
<RowDefinition Height="100"/>
</Grid.RowDefinitions>
<Border Background="#FF6C6C6C">
<Grid>
<TextBlock HorizontalAlignment="Center" TextWrapping="Wrap" Text="Hey, I here is some really cool content." VerticalAlignment="Top" FontSize="32" FontFamily="Segoe UI Light" TextAlignment="Center" Margin="0,50,0,0"/>
<CheckBox Content="I want to see more" HorizontalAlignment="Center" VerticalAlignment="Bottom" Margin="0,0,0,15" IsChecked="{Binding ShowAdditionalContent}">
<i:Interaction.Behaviors>
<ei:DataStateBehavior Binding="{Binding ShowAdditionalContent}" Value="False" TrueState="Normal" FalseState="Extended"/>
</i:Interaction.Behaviors>
</CheckBox>
<Button Content="" HorizontalAlignment="Right" VerticalAlignment="Top" FontFamily="Segoe UI Symbol" FontSize="21.333" Style="{DynamicResource ButtonStyle}" Margin="0,5,5,0" Click="CloseMainWindow"/>
</Grid>
</Border>
<Border Grid.Row="1" Background="#FF383838">
<TextBlock x:Name="TextBlock" TextWrapping="Wrap" Text="You can see this, when the check box is activated." FontFamily="Segoe UI Light" FontSize="18.667" TextAlignment="Center" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="Silver"/>
</Border>
</Grid>
</Window>
The aspects you have to notice are the following:
The main window consists of a grid whose second row is hidden by default. This is achieved by setting the window height to 300 while the grid actually uses 400 logical units. One could also calculate this height dynamically during runtime, but for this simple example, this is not necessary.
The second row becomes visible when the "Extended" visual state is activated. This is actually done using the check box which updates the corresponding view model and the attached DataStateBehavior (this is part of the Blend SDK) that responds to it. When the state is changed, this behavior ensures that the corresponding visual state is activated, i.e. "Normal" when the checkbox is unchecked and "Extended" when it is checked.
The WindowStyle is set to None and the ResizeMode is set to NoResize. This ensures that no border is shown around the window. There is also the option to set AllowTransparency to true but I wouldn't recommend that as this has some serious performance implications. Notice that the default Minimize, Maximize/Restore and Quit buttons will not be present in this modus, too.
Please feel free to ask if you have further questions.

Can I change the VisualState of a DataTemplate in a ItemTemplate?

I have some controls in a DataTemplate and I'd like to control it's pressed state behaviour. I did the following where I just put in VisualStateManager in the DataTemplate but it doesn't seem to work. I think it's possible to understand what I'm trying to do below. Is it possible to do it inline inside the DataTemplate tags?
<ItemsControl ItemsSource="{Binding Items}">
....
<ItemsControl.ItemTemplate>
<DataTemplate>
<Grid ...>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
...
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="BorderThickness" Storyboard.TargetName="GridItemBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="3"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Border" ...>
...
</Border>
</Grid>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
The short answer is that there is no "Pressed" visual state for the control type you're targeting -- so while you can reference any state in the Visual State Manager, it won't matter, because the control's code will never put it into that state.
You can see which visual states a control supports by looking at its definition (they're declared using the TemplateVisualState attribute), or by looking at this section on MSDN.
The way to go here might be to use the Button (or an override of [ButtonBase][2] that you write), since that has the "Pressed" visual state built in. You'd just have to write a Control Template for it that provides the layouts/styles that you're after.
Edit Here's an example:
Control template (resources section). This is a control template for the Button control, but it's not really a button. I'm just using it to take advantage of the "Pressed" visual state functionality.
<ControlTemplate x:Key="MyButtonTemplate" TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Pressed">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(Border.BorderThickness)" Storyboard.TargetName="GridItemBorder">
<DiscreteObjectKeyFrame KeyTime="0" Value="3"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="GridItemBorder" BorderBrush="Orange" BorderThickness="1" Background="White">
<ContentPresenter Content="{TemplateBinding Content}" />
</Border>
</Grid>
</ControlTemplate>
Items control
Define the item template as a "Button" which uses the above ControlTemplate.
<ItemsControl ItemsSource="{Binding SelectedItems}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Template="{StaticResource MyButtonTemplate}" Content="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>

Applying visual state to Border element

I am learning how to work with VisualStates, and have this problem:
I have a Control template which has Grid inside, and grid contains image and two TextBlocks. I would like to place a rectangle whenever a mouse if over a control. Most of the examples on internet use Blend, which I currently don't have, and also I would like to learn to do this manually. Here is a simple template (I have used constant colors to make it simpler):
<ControlTemplate x:Key="MyControlTemplate" TargetType="SomeControl">
<Grid Cursor="Hand" Width="Auto">
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Image Grid.RowSpan="2" HorizontalAlignment="Left" VerticalAlignment="Top" Stretch="None" Source="{Binding ImageUrl}" />
<TextBlock x:Name="TitleElement" Grid.Column="1" Margin="4" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Content}" Foreground="{StaticRecource TitleForegroundBrush}" />
<TextBlock x:Name="DescriptionElement" Grid.Row="1" Grid.Column="1" Margin="4,0,4,4" MaxWidth="200" TextWrapping="Wrap" HorizontalAlignment="Left" VerticalAlignment="Top" Text="{Binding Description}" Foreground="{StaticResource DescriptionElementForeground}" />
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TitleElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource TitleElementFocusedForeground}" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Grid>
</ControlTemplate>
Changing the TitleElement's Foreground on mouse over is working. Now I would like to have a border over whole control on mouse over (not just part of it). First thing I tried is placing a Border as a container of grid and putting a StoryBoard inside VisualStateGroup:
<Border x:Name="ControlBorder" BorderBrush="{StaticResource ControlBorderBrush}" BorderThickness="0">
<Grid Cursor="Hand" Width="Auto">
....
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Unfocused"/>
<VisualState x:Name="Focused">
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TitleElement" Storyboard.TargetProperty="Foreground">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="{StaticResource TitleElementFocusedForeground}" />
</ObjectAnimationUsingKeyFrames>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="ControlBorder" Storyboard.TargetProperty="BorderThickness">
<DiscreteObjectKeyFrame KeyTime="00:00:00" Value="1" />
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
This didn't work, as a matter of fact, now TitleElement doesn't even change foreground color, as it used to. However, adding a Border as 4th element inside a grid (RowSpan and ColumnSpan set to whole grid) works!, but there are some side affects which I don't like, for example, rectangle is "blinking" when I am moving mouse over control. Questions:
Why putting Grid inside Rectangle doesn't work, but putting Rectangle inside grid works?
I see that there is a CommonStates VisualGroup, which must be predefined somewhere. How do we know which ones are predefined, and their respective names?
What is the scope of VisualStateManager? If I define it inside an element, does it belong just to that element, or whole ControlTemplate?
Thanks.
Visual states need to be managed on the root element of the control template, if you put an element around your root they will be ignored, you will need to move them up.
On the styles and templates page of the controls the specific states are listed, common states should be the same for all (as they are "common"), the ones which are supported are also listed on the pages for the controls. (e.g. Button has Normal, Pressed, MouseOver and Disabled)
Applies to the whole template (see 1.)

Using Raster Images in Silverlight for buttons

I have buttons supplied to me from photoshop for different button states.
It looks like this
<Button x:Name="ResultsBtn" Click="ResultsBtn_Click" FontSize="27" BorderThickness="0" Padding="-10" Margin="-10">
<Grid>
<Image Source="..But_01_Idle.png" Width="496"/>
<TextBlock Text="Results" Margin="174,21,172,23" Width="90" Height="40" Foreground="White" />
</Grid>
</Button>
The button looks right for just one state.
I want to use expression blend to record a state and change the background behind an image (in this instance an outer glow) or change the source on a state change.
I've noticed that blend only seems to record position and transforms and not changes in attributes.
Should I be doing this in code or rather have the photoshop file sent in a particular format so that it can be automatically converted by blend
Okay, I'm actually quite surprised at Blend: it does not seem to allow you to animate the source property. However, Silverlight allows it so I assume WP7 will also allow it; this looks like a bug in Blend 4. However, I still would not recommend it using an image based approach because the images will deform and look bad/pixelated when significantly scaled up or down. A better approach is to edit your button's control template and modify it to match your reference artwork. You can even using File -> Import Adobe Photoshop File ... to pull the basic artwork into Blend. Then it's just a matter of shuffling it into the control template.
If you're dead set on using images (which will increase the size of your XAP and actually cause slower load UserControl load times), you can go about it as follows in Blend:
Create a new project and add a Button to your root visual element.
Create a new project folder called Images and add two images to it. (I used Koala.jpg and Penguins.jpg from the Sample Pictures folder.)
Right click the button and select Edit Template -> Edit a Copy...
The default template will contain a Grid that contains a Border named Background. Inside the Background border is a Grid that contains a Rectangle and another Border. Delete both of those innermost elements.
Now add an Image as a child of the Background border's Grid.
Now switch to the XAML editor and modify your control template's visual state groups to match the following code. (Look for the two "Added" comment blocks.)
Run the project. On mouse over you'll see penguins. Click and hold the left mouse and you'll see a koala.
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Grid>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal"/>
<VisualState x:Name="MouseOver">
<!-- Added -->
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TheImage" Storyboard.TargetProperty="Source">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="/Images/Penguins.jpg"/>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
<!-- End of Added -->
</VisualState>
<VisualState x:Name="Pressed">
<Storyboard>
<ColorAnimation Duration="0" To="#FF6DBDD1" Storyboard.TargetProperty="(Border.Background).**(SolidColorBrush.Color)" Storyboard.TargetName="Background"/>
<!-- Added -->
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="TheImage" Storyboard.TargetProperty="Source">
<DiscreteObjectKeyFrame KeyTime="0:0:0" Value="/Images/Koala.jpg"/>
</ObjectAnimationUsingKeyFrames>**
<!-- End of Added -->
</Storyboard>
</VisualState>
<VisualState x:Name="Disabled">
<Storyboard>
<DoubleAnimation Duration="0" To=".55" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="DisabledVisualElement"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
<VisualStateGroup x:Name="FocusStates">
<VisualState x:Name="Focused">
<Storyboard>
<DoubleAnimation Duration="0" To="1" Storyboard.TargetProperty="Opacity" Storyboard.TargetName="FocusVisualElement"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Unfocused"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<Border x:Name="Background" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="White" CornerRadius="3">
<Grid Background="{TemplateBinding Background}" Margin="1">
<Image x:Name="TheImage" Source=""/>
</Grid>
</Border>
<ContentPresenter x:Name="contentPresenter" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}"/>
<Rectangle x:Name="DisabledVisualElement" Fill="#FFFFFFFF" IsHitTestVisible="false" Opacity="0" RadiusY="3" RadiusX="3"/>
<Rectangle x:Name="FocusVisualElement" IsHitTestVisible="false" Margin="1" Opacity="0" RadiusY="2" RadiusX="2" Stroke="#FF6DBDD1" StrokeThickness="1"/>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
Visual States are built with animations, so you can only change things that can be animated (and expect typical results). I've never tried it, but my instinct tells me an Image source cannot be animated so the VSM is probably not a viable way to manage that.
Opacity, however, can be animated, so you could have both Image's in ytour button and control their Opacity with States. Just a thought.
You have to create a ControlTemplate:
Code for Button:
<Button Template={DynamicResource ButtonTemplate}/>
In your Resource Dictionary:
<ControlTemplate x:Key="ButtonTemplate" {x:Type Button}>
<Grid Padding="-10" Margin="-10">
<Image x:Name="IdleState" Source="..But_01_Idle.png" Width="496"/>
<Image x:Name="MouseOverState" Source="..But_01_MouseOver.png" Width="496"/>
<Image x:Name="PressedState..." etc/>
<TextBlock Text="Results" Margin="174,21,172,23" Width="90" Height="40" Foreground="White" FontSize="27"/>
</Grid>
</ControlTemplate>
Then, in Blend, Edit the Template and you'll find the States as Mike said. Use the Properties panel to hide / show your images for each state you want to style and you should be done.

DataTrigger is not using GoToStateAction in Silverlight

The follow XAML represents an object I am trying to build in Expression Blend. I am having trouble with the DataTrigger in the StackPanel - the application does not go to Empty when the trigger matches the data. Further explanation is after this code:
<DataTemplate x:Key="SampleTemplate">
<StackPanel x:Name="SampleStack" Style="{StaticResource DefaultSampleStyle}" Width="64" Height="60">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0">
<Storyboard>
<ColorAnimation Duration="0" To="#FFDFE04B" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="SampleStack" d:IsOptimized="True"/>
</Storyboard>
</VisualTransition>
</VisualStateGroup.Transitions>
<VisualState x:Name="Empty">
<Storyboard>
<ColorAnimation Duration="0" To="#FF4B6FE0" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="SampleStack" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<VisualStateManager.CustomVisualStateManager>
<ei:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
<i:Interaction.Triggers>
<ei:DataTrigger Binding="{Binding IsActive}" Value="False">
<ei:GoToStateAction StateName="Empty" UseTransitions="False"/>
</ei:DataTrigger>
</i:Interaction.Triggers>
<TextBlock x:Name="StartOn" Text="{Binding StartOn, StringFormat=hh:mm}"/><TextBlock x:Name="textBlock" Text="-" />
<TextBlock x:Name="EndOn" Text="{Binding EndOn, StringFormat=hh:mm}"/>
</StackPanel>
</DataTemplate>
If I use an EventTrigger with a Loaded value, the Empty state is correctly applied based on the IsActive binding.
If I use the existing DataTrigger and change a Property on the Stackpanel, such as Height, based on the binding of IsActive this also works.
Am I doing something fundamentally wrong in the XAML? Do you need a more complete example of the XAML to understand the issue?
do you need the GoToStateAction?
I guess, the problem is the Binding "at startup". I added a dispatcher and threw the NotifyPropertyChanged again after one second. Then it works. Propably you can workaround it like this. You wait till the control is loaded and then throw the PropertyChanged again. This is not a nice way and similar to your idea (If I use an EventTrigger with a Loaded value,...)
I would recommend you to use a DataStateBehaviour. If you hav a boolean to decide in which satte you have to go, this is great. It is a behaviour where you can bind the condition to a property and then set a true and a false state.
It would look like this (I did a few adjustments just for testing at my computer):
<DataTemplate x:Key="SampleTemplate">
<StackPanel x:Name="SampleStack" Width="64" Height="60" Background="White">
<i:Interaction.Behaviors>
<ei:DataStateBehavior Binding="{Binding IsChecked}" Value="True" TrueState="Empty" FalseState="Base"/>
</i:Interaction.Behaviors>
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="VisualStateGroup">
<VisualStateGroup.Transitions>
<VisualTransition GeneratedDuration="0"/>
</VisualStateGroup.Transitions>
<VisualState x:Name="Empty">
<Storyboard>
<ColorAnimation Duration="0" To="Red" Storyboard.TargetProperty="(Panel.Background).(SolidColorBrush.Color)" Storyboard.TargetName="SampleStack" d:IsOptimized="True"/>
</Storyboard>
</VisualState>
<VisualState x:Name="Base"/>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
<VisualStateManager.CustomVisualStateManager>
<ei:ExtendedVisualStateManager/>
</VisualStateManager.CustomVisualStateManager>
<TextBlock x:Name="StartOn" Text="Test"/>
</StackPanel>
</DataTemplate>
As you can see I added a second state to the VisualStateGroup (There is now empty and base). I would recommend this not only because the DataStateBehaviour needs at least two states in one group. If you have only one state, you have no chance to change the state of this group back to normal, e.g.
I hope this answer helps you.
BR,
TJ

Resources