locked
Issue With Visual States

    Question

  • I'm trying to convert my controls that had Triggers to now use Visual States instead but I can't seem to get it working.  With the following code the initial Grid shown is the correct one but nothing ever changes when "IsPlaying" changes.  Can anyone see what the problem could be?

    <ToggleButton x:Name="ButtonPlay" IsChecked="{Binding IsPlaying}" Click="ButtonPlay_Click">
                                <ToggleButton.Template>
                                    <ControlTemplate>
                                        <Grid Width="80" Height="80" Visibility="Visible">
                                            <VisualStateManager.VisualStateGroups>
                                                <VisualStateGroup x:Name="CheckedStates">
                                                    <VisualState x:Name="Checked">
                                                        <Storyboard>
                                                            <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="0"/>
                                                            <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="1"/>
                                                        </Storyboard>
                                                    </VisualState>
                                                    <VisualState x:Name="Unchecked">
                                                        <Storyboard>
                                                            <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="1"/>
                                                            <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="0"/>
                                                        </Storyboard>
                                                    </VisualState>
                                                </VisualStateGroup>
                                            </VisualStateManager.VisualStateGroups>
                                            <Rectangle Fill="Transparent" Visibility="Visible" />
                                            <Grid x:Name="Play">
                                                <Path Data="F1M281.119,499.433L259.192,515.433 237.265,531.433 237.265,499.433 237.265,467.433 259.192,483.433 281.119,499.433z" 
                                                  Stretch="Uniform" Fill="{StaticResource DarkFlowGradientBrush}" Width="44" Height="44" Margin="0,0,0,0" />
                                            </Grid>
                                            <Grid x:Name="Pause">
                                                <Path Data="M41.779349,0.00013073589L48.738728,0.00013073589C52.588314,0.00013083723,55.697983,3.1040558,55.697983,6.9079523L55.697983,55.760313C55.697983,59.564207,52.588314,62.668135,48.738728,62.668135L41.779349,62.668135C37.929763,62.668135,34.810083,59.564207,34.810083,55.760313L34.810083,6.9079523C34.810083,3.1040558,37.929763,0.00013083723,41.779349,0.00013073589z M6.9602375,0L13.930473,0C17.770603,0,20.890709,3.1033384,20.890709,6.9074301L20.890709,55.759981C20.890709,59.564074,17.770603,62.667414,13.930473,62.667414L6.9602375,62.667414C3.1201077,62.667414,0,59.564074,0,55.759981L0,6.9074301C0,3.1033384,3.1201077,0,6.9602375,0z" 
                                                  Stretch="Uniform" Fill="{StaticResource DarkFlowGradientBrush}" Width="44" Height="44" Margin="0,0,0,0" >
                                                </Path>
                                            </Grid>
                                        </Grid>
                                    </ControlTemplate>
                                </ToggleButton.Template>
                            </ToggleButton>

    Wednesday, September 5, 2012 1:47 PM

Answers

  • ToggleButton restyling:

    <Page
        x:Class="App1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        <Page.Resources>
            <Style x:Key="ToggleButtonStyle" TargetType="ToggleButton">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ToggleButton">
                            <Grid>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="PointerOver">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="0"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="1"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Normal">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="0"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="1"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Checked">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="1"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="0"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="CheckedPointerOver">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="1"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="0"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="CheckedPressed">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="1"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="0"/>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Rectangle Fill="Transparent" Visibility="Visible" />
                                <Grid x:Name="Play">
                                    <Path Data="F1M281.119,499.433L259.192,515.433 237.265,531.433 237.265,499.433 237.265,467.433 259.192,483.433 281.119,499.433z" 
                                                  Stretch="Uniform" Fill="Red" Width="44" Height="44" Margin="0,0,0,0" />
                                </Grid>
                                <Grid x:Name="Pause">
                                    <Path Data="M41.779349,0.00013073589L48.738728,0.00013073589C52.588314,0.00013083723,55.697983,3.1040558,55.697983,6.9079523L55.697983,55.760313C55.697983,59.564207,52.588314,62.668135,48.738728,62.668135L41.779349,62.668135C37.929763,62.668135,34.810083,59.564207,34.810083,55.760313L34.810083,6.9079523C34.810083,3.1040558,37.929763,0.00013083723,41.779349,0.00013073589z M6.9602375,0L13.930473,0C17.770603,0,20.890709,3.1033384,20.890709,6.9074301L20.890709,55.759981C20.890709,59.564074,17.770603,62.667414,13.930473,62.667414L6.9602375,62.667414C3.1201077,62.667414,0,59.564074,0,55.759981L0,6.9074301C0,3.1033384,3.1201077,0,6.9602375,0z" 
                                                  Stretch="Uniform" Fill="Green" Width="44" Height="44" Margin="0,0,0,0" >
                                    </Path>
                                </Grid>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Page.Resources>
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <StackPanel>
                <ToggleButton IsChecked="{Binding Path=UserRead, Mode=TwoWay}" Style="{StaticResource ToggleButtonStyle}" IsTabStop="False" Margin="5"/>
                <ToggleButton IsChecked="{Binding Path=UserRead, Mode=TwoWay}" Style="{StaticResource ToggleButtonStyle}" IsTabStop="True" Margin="5"/>
                <ToggleButton IsChecked="{Binding Path=UserRead, Mode=TwoWay}" Style="{StaticResource ToggleButtonStyle}" IsTabStop="False" Margin="5"/>
            </StackPanel>
        </Grid>
    </Page>
    

    -

    using System.ComponentModel;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Navigation;
    
    namespace App1
    {
        public sealed partial class MainPage : Page
        {
            KiwiItem item;
            public MainPage()
            {
                this.DataContext = this.item = new KiwiItem();
                this.InitializeComponent();
            }
        }
    
        /// <summary>
        /// 
        /// </summary>
        public class KiwiItem : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            bool userRead;
            public bool UserRead
            {
                get { return userRead; }
                set
                {
                    userRead = value;
                    OnPropertyChanged("UserRead");
                }
            }
        }
    }
    

    • Marked as answer by StormENT Thursday, September 6, 2012 11:50 AM
    • Unmarked as answer by StormENT Thursday, September 6, 2012 11:51 AM
    • Marked as answer by StormENT Thursday, September 6, 2012 11:55 AM
    Wednesday, September 5, 2012 6:41 PM

All replies

  • Does this work: [x:Name="Unchecked"] -> [x:Name="Normal"]
    Wednesday, September 5, 2012 2:30 PM
  • That doesn't work, I'm also having issues with a Listbox Item. Can I set Visual States where I am trying (I.E in the control declaration)  or do they have to be defined in a separate style resource as I have certain states defined in a resource dictionary that are working but this does not.
    <ListBox.ItemTemplate>
                    <DataTemplate>                    
                        <Grid x:Name="poster" Background="{StaticResource DarkFlowBackground}" 
                                  Height="200"
                                  Width="135"
                              DoubleTapped="poster_DoubleTapped">
                            <VisualStateManager.VisualStateGroups>
                                <VisualStateGroup x:Name="SelectionStates">
                                    <VisualState x:Name="Selected">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="posterGlow" Storyboard.TargetProperty="Opacity" From="0" 
                                       To="0.8" Duration="0:0:0.5" />
                                        </Storyboard>
                                    </VisualState>
                                    <VisualState x:Name="Unselected">
                                        <Storyboard>
                                            <DoubleAnimation Storyboard.TargetName="posterGlow" Storyboard.TargetProperty="Opacity" From="0.8" 
                                       To="1" Duration="0:0:0.5" />
                                        </Storyboard>
                                    </VisualState>
                                </VisualStateGroup>
                            </VisualStateManager.VisualStateGroups>
                            <Border x:Name="posterGlow"/>
                            <Grid Margin="5,5,5,5">
                                <!--Content Here-->
                            </Grid>                        
                        </Grid>
                    </DataTemplate>
                </ListBox.ItemTemplate>


    • Edited by StormENT Wednesday, September 5, 2012 5:13 PM
    Wednesday, September 5, 2012 5:12 PM
  • ToggleButton restyling:

    <Page
        x:Class="App1.MainPage"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App1"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d">
        <Page.Resources>
            <Style x:Key="ToggleButtonStyle" TargetType="ToggleButton">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="ToggleButton">
                            <Grid>
                                <VisualStateManager.VisualStateGroups>
                                    <VisualStateGroup x:Name="CommonStates">
                                        <VisualState x:Name="PointerOver">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="0"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="1"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Normal">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="0"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="1"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="Checked">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="1"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="0"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="CheckedPointerOver">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="1"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="0"/>
                                            </Storyboard>
                                        </VisualState>
                                        <VisualState x:Name="CheckedPressed">
                                            <Storyboard>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Play" Storyboard.TargetProperty="Opacity" To="1"/>
                                                <DoubleAnimation Duration="0" Storyboard.TargetName="Pause" Storyboard.TargetProperty="Opacity" To="0"/>
                                            </Storyboard>
                                        </VisualState>
                                    </VisualStateGroup>
                                </VisualStateManager.VisualStateGroups>
                                <Rectangle Fill="Transparent" Visibility="Visible" />
                                <Grid x:Name="Play">
                                    <Path Data="F1M281.119,499.433L259.192,515.433 237.265,531.433 237.265,499.433 237.265,467.433 259.192,483.433 281.119,499.433z" 
                                                  Stretch="Uniform" Fill="Red" Width="44" Height="44" Margin="0,0,0,0" />
                                </Grid>
                                <Grid x:Name="Pause">
                                    <Path Data="M41.779349,0.00013073589L48.738728,0.00013073589C52.588314,0.00013083723,55.697983,3.1040558,55.697983,6.9079523L55.697983,55.760313C55.697983,59.564207,52.588314,62.668135,48.738728,62.668135L41.779349,62.668135C37.929763,62.668135,34.810083,59.564207,34.810083,55.760313L34.810083,6.9079523C34.810083,3.1040558,37.929763,0.00013083723,41.779349,0.00013073589z M6.9602375,0L13.930473,0C17.770603,0,20.890709,3.1033384,20.890709,6.9074301L20.890709,55.759981C20.890709,59.564074,17.770603,62.667414,13.930473,62.667414L6.9602375,62.667414C3.1201077,62.667414,0,59.564074,0,55.759981L0,6.9074301C0,3.1033384,3.1201077,0,6.9602375,0z" 
                                                  Stretch="Uniform" Fill="Green" Width="44" Height="44" Margin="0,0,0,0" >
                                    </Path>
                                </Grid>
                            </Grid>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </Page.Resources>
        <Grid Background="{StaticResource ApplicationPageBackgroundThemeBrush}">
            <StackPanel>
                <ToggleButton IsChecked="{Binding Path=UserRead, Mode=TwoWay}" Style="{StaticResource ToggleButtonStyle}" IsTabStop="False" Margin="5"/>
                <ToggleButton IsChecked="{Binding Path=UserRead, Mode=TwoWay}" Style="{StaticResource ToggleButtonStyle}" IsTabStop="True" Margin="5"/>
                <ToggleButton IsChecked="{Binding Path=UserRead, Mode=TwoWay}" Style="{StaticResource ToggleButtonStyle}" IsTabStop="False" Margin="5"/>
            </StackPanel>
        </Grid>
    </Page>
    

    -

    using System.ComponentModel;
    using Windows.UI.Xaml;
    using Windows.UI.Xaml.Controls;
    using Windows.UI.Xaml.Controls.Primitives;
    using Windows.UI.Xaml.Navigation;
    
    namespace App1
    {
        public sealed partial class MainPage : Page
        {
            KiwiItem item;
            public MainPage()
            {
                this.DataContext = this.item = new KiwiItem();
                this.InitializeComponent();
            }
        }
    
        /// <summary>
        /// 
        /// </summary>
        public class KiwiItem : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
            private void OnPropertyChanged(string propertyName)
            {
                if (PropertyChanged != null)
                    PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            bool userRead;
            public bool UserRead
            {
                get { return userRead; }
                set
                {
                    userRead = value;
                    OnPropertyChanged("UserRead");
                }
            }
        }
    }
    

    • Marked as answer by StormENT Thursday, September 6, 2012 11:50 AM
    • Unmarked as answer by StormENT Thursday, September 6, 2012 11:51 AM
    • Marked as answer by StormENT Thursday, September 6, 2012 11:55 AM
    Wednesday, September 5, 2012 6:41 PM
  • Thanks ForInfo that worked like a charm. I even have it working by declaring in my controls template and not a separate style as

    <ToggleButton x:Name="ButtonPlay" IsChecked="{Binding IsPlaying}" Click="ButtonPlay_Click">
                                <ToggleButton.Template>
                                    <ControlTemplate>
                                        <Grid Width="80" Height="80" Visibility="Visible">
                                            <VisualStateManager.VisualStateGroups>......
    Looking at the code it looks like I was putting my declaration in the VisualStateGroup of "CheckedStates" whereas it should have been in "CommonStates".
    Thanks as always for the clarification and help.
    Thursday, September 6, 2012 11:55 AM
  • Great! I recreated it by pruning stepwise the original Style to what you wanted keeping in mind that the different states are not 'ored' together but mutually exclusive to one another.

    Sometimes one would really wish to have a solid exception [and Message] thrown when VisualStates(Transitions) are incoherent/absent with respect to the templated FrameworkElement ;-)


    • Edited by ForInfo Thursday, September 6, 2012 12:02 PM
    Thursday, September 6, 2012 12:02 PM