locked
VisualStateManager.GoToState allways returns false. RRS feed

  • Question

  • I'v created my custom user control, and I wish to react on controls visual states changes. Unfortunatly, whenever I try to change the VisualState, it fails (GoToState returns false). What am I doing wrong? Here is the code, it's pretty simple:

        [TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
        [TemplateVisualState(Name = "Selected", GroupName = "CommonStates")]
        [TemplateVisualState(Name = "PointerOver", GroupName = "CommonStates")]
        public sealed partial class MyUserControl1 : UserControl
        {
            /// <summary>
            /// Constructors
            /// </summary>
            public MyUserControl1()
            {
                this.InitializeComponent();
            }
            static MyUserControl1()
            {
                IsSelectedProperty = DependencyProperty.Register("IsSelected", typeof(bool), typeof(MyUserControl1), new PropertyMetadata(false, (d, e) => { (d as MyUserControl1).ChangeState(); }));
            }
    
            /// <summary>
            /// Dependency Properties
            /// </summary>
            public static readonly DependencyProperty IsSelectedProperty;
            public bool IsSelected
            {
                get { return (bool)this.GetValue(IsSelectedProperty); }
                set { this.SetValue(IsSelectedProperty, value); }
            }
    
            /// <summary>
            /// Calls is mouse over.
            /// </summary>
            private void btnMain_PointerInOut(object sender, PointerRoutedEventArgs e)
            {
                ChangeState();
            }
    
            /// <summary>
            /// Changes the state
            /// </summary>
            private void ChangeState()
            {
                if (this.ExampleButton.IsPointerOver)
                    VisualStateManager.GoToState(this, "PointerOver", true); // Allways return false :(
                else if (this.IsSelected)
                    VisualStateManager.GoToState(this, "Selected", true); // Allways return false :(
                else
                    VisualStateManager.GoToState(this, "Normal", true); // Allways return false :(
            }
        }

    <UserControl
        x:Class="App5.MyUserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App5"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">
        
        <Button Name="ExampleButton" Height="100" Width="100" PointerEntered="btnMain_PointerInOut" PointerExited="btnMain_PointerInOut" />
    
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="CommonStates" >
                <VisualState x:Name="Selected" >
                    <Storyboard>
                        <ColorAnimation
                            Storyboard.TargetName="ExampleButton"
                            Storyboard.TargetProperty="Background"
                            To="Blue"
                            Duration="0" />
                    </Storyboard>
                </VisualState>
                <VisualState x:Name="PointerOver">
                    <Storyboard>
                        <ColorAnimation
                            Storyboard.TargetName="ExampleButton"
                            Storyboard.TargetProperty="Background"
                            To="Red"
                            Duration="0"/>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
    </UserControl>


    Monday, October 29, 2012 9:24 PM

Answers

  • I'v created sample in Expression Blend and it showed me how to use it properly. The problem was that VisualStateManager XAML code was in the wrong place.
    • Marked as answer by Jonatan Dragon Tuesday, October 30, 2012 5:48 PM
    Tuesday, October 30, 2012 5:48 PM

All replies

  • Hi joni55,

    In your code I find that you use "this" which represent the custom user control (MyUserControl1) in the method VisualStateManager.GoToState(this, "PointerOver", true);

    However, you actual add the PointerEntered event on the Button control instead of the custom user control (MyUserControl1). So, you need to change your code to be:

     private void ChangeState()
            {
                 bool state;
                if (this.ExampleButton.IsPointerOver)
                    state = VisualStateManager.GoToState((Button)this.ExampleButton, "PointerOver", true); 
                else if (this.IsSelected)
                    VisualStateManager.GoToState((Button)this.ExampleButton, "Selected", true); 
                else
                    VisualStateManager.GoToState((Button)this.ExampleButton, "Normal", true); 
            }
    Thanks.

    Vicky Song [MSFT]
    MSDN Community Support | Feedback to us

    Tuesday, October 30, 2012 7:04 AM
    Moderator
  • Unfortunatly, this way I will change the VisualState of a Button, not of MyUserControl1 - it's not my goal.

    As you can see, I have defined VisualStates for UserControl, becous it's UserControl whom states I want to change.

      [TemplateVisualState(Name = "Normal", GroupName = "CommonStates")]
      [TemplateVisualState(Name = "Selected", GroupName = "CommonStates")]
      [TemplateVisualState(Name = "PointerOver", GroupName = "CommonStates")]

    You are right, it's button rising VisualState change, but it's only becouse in this particular case, button covers my whole user control. The question is, why can't I change VisualState of a UserControl?

    Tuesday, October 30, 2012 3:46 PM
  • There is possibly a mismatch due to the animation setting the 'Background.Brush' property to a Color value instead of to a Brush value.

    To resolve the conflict, could you try this variant:

    <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates" >
                    <VisualState x:Name="Selected" >
                        <Storyboard>
                            <ColorAnimation
                            Storyboard.TargetName="ExampleButton"
                            Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
                            To="Blue"
                            Duration="0" />
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="PointerOver">
                        <Storyboard>
                            <ColorAnimation
                            Storyboard.TargetName="ExampleButton"
                            Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
                            To="Red"
                            Duration="0"/>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>

    Tuesday, October 30, 2012 4:19 PM
  • Thank you very much for the answer. You are right, it's one of the reason why it doesn't works.

    Unfortunatly, the main problem is still unsolved.

    Whenever I call this method:

      VisualStateManager.GoToState(...)

    it allways returns false. Mayby my idea is wrong? Can I set VisualState to a UserControl, inside it? - or do I need especially created Template to set control's VisualState? Please, help.

    Tuesday, October 30, 2012 4:32 PM
  • I'v created sample in Expression Blend and it showed me how to use it properly. The problem was that VisualStateManager XAML code was in the wrong place.
    • Marked as answer by Jonatan Dragon Tuesday, October 30, 2012 5:48 PM
    Tuesday, October 30, 2012 5:48 PM
  • Can you show us the solution?
    Tuesday, April 8, 2014 4:43 PM
  • Sure, the solution is very simple. Just wrap your control and VisualStateGroups inside a Panel control, like Grid.

    <UserControl
        x:Class="App1.MyUserControl1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="using:App5"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        mc:Ignorable="d"
        d:DesignHeight="300"
        d:DesignWidth="400">
    
        <Grid>
            <Button Name="ExampleButton" Height="100" Width="100" PointerEntered="btnMain_PointerInOut" PointerExited="btnMain_PointerInOut" />
    
            <VisualStateManager.VisualStateGroups>
                <VisualStateGroup x:Name="CommonStates" >
                    <VisualState x:Name="Selected" >
                        <Storyboard>
                            <ColorAnimation
                            Storyboard.TargetName="ExampleButton"
                            Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
                            To="Blue"
                            Duration="0" />
                        </Storyboard>
                    </VisualState>
                    <VisualState x:Name="PointerOver">
                        <Storyboard>
                            <ColorAnimation
                            Storyboard.TargetName="ExampleButton"
                            Storyboard.TargetProperty="(Button.Background).(SolidColorBrush.Color)"
                            To="Red"
                            Duration="0"/>
                        </Storyboard>
                    </VisualState>
                </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
    
        </Grid>
    
    </UserControl>

    Wednesday, April 9, 2014 8:56 PM