How can I use VisualStates in a ChildWindow?
Asked Answered
G

4

1

Is there any way to use the VisualStateManager with my ChildWindow subclass? Calls to VisualStateManager do nothing, and the googling I did implied the only way to achieve this is with manual calls to Storyboards. That's so much sloppier and prone to error. Has anyone found a way to achieve it?

Updated with example code. To use it, just create a new Silverlight Project, and call ExampleWindow.ShowWindow() from a button click on the main page. You'll see the button, even though the constructor sets the state that should hide the button.

XAML (ExampleWindow.xaml):

<controls:ChildWindow
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    mc:Ignorable="d"
    xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
    x:Class="Client.Windows.ExampleWindow"
    Title="Example">
    <Grid x:Name="LayoutRoot">
        <VisualStateManager.VisualStateGroups>
            <VisualStateGroup x:Name="ExampleStateGroup">
                <VisualState x:Name="ExampleBaseState">
                    <Storyboard>
                        <DoubleAnimationUsingKeyFrames BeginTime="00:00:00" Duration="00:00:00.0010000" Storyboard.TargetName="button" Storyboard.TargetProperty="(UIElement.Opacity)">
                            <EasingDoubleKeyFrame KeyTime="00:00:00" Value="0"/>
                        </DoubleAnimationUsingKeyFrames>
                    </Storyboard>
                </VisualState>
            </VisualStateGroup>
        </VisualStateManager.VisualStateGroups>
        <VisualStateManager.CustomVisualStateManager>
            <ic:ExtendedVisualStateManager/>
        </VisualStateManager.CustomVisualStateManager>
        <Button x:Name="button" Content="You Shouldn't See Me" Grid.ColumnSpan="2" Width="150" Height="150" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
</controls:ChildWindow>

Code Behind (ExampleWindow.xaml.cs):

using System.Windows;
using System.Windows.Controls;

namespace Client.Windows
{
    public partial class ExampleWindow : ChildWindow
    {
        public ExampleWindow()
        {
            InitializeComponent();

            VisualStateManager.GoToState( this, "ExampleBaseState", true );
        }

        public static void ShowWindow()
        {
            var w = new ExampleWindow();
            w.Show();
        }
    }
}
Gilburt answered 22/1, 2010 at 16:41 Comment(2)
I can't think off the top of my head why ChildWindow's wouldn't be able to use a VisualStateManager, perhaps you should show us some of your code?Manis
I think it has to do with the ChildWindow's template having Open and Closed VisualStates, so the VisualTree search for VisualStateGroups stops there and doesn't continue to the control's states (though it works fine in Blend at design-time).Gilburt
G
0

So far, the only workaround I've found is to put anything that requires visual states into a UserControl. The UserControl can have states, and successfully switch between them, and communicate anything necessary to the ChildWindow through events, methods, and properties.

Gilburt answered 25/1, 2010 at 16:29 Comment(0)
P
1

Check this post Using Visual State Manager with Silverlight Toolkit’s Child Windows control

Prehensile answered 1/10, 2010 at 2:36 Comment(0)
G
0

So far, the only workaround I've found is to put anything that requires visual states into a UserControl. The UserControl can have states, and successfully switch between them, and communicate anything necessary to the ChildWindow through events, methods, and properties.

Gilburt answered 25/1, 2010 at 16:29 Comment(0)
L
0

I experienced the same issue with VSM not working in ChildWindows as Dov. What I did was to change my ChildWindow into a UserControl and then set the UserControl as the Content of a generic ChildWindow before opening it up.

var childWindow = new ChildWindow { Content = someUserControl };

The problem now is that you lose the DialogResult functionality of the ChildWindow class since your code-behing will be in the UserControl. The simplest way to access the DialogResult Property of the ChildWindow is to just use the Parent Property inside of the UserControl.

Loupe answered 24/2, 2010 at 8:24 Comment(1)
That sounds like what I ended up doing, pretty much.Gilburt
N
0

The ChildWindow Template contains a VisualStateManager that manages the VisualStateGroup "CommonStates" for common child window animations. When you call the VisualStateManager.GoToState it is looking for the state in the ChildWindow Template CommonStates VisualStateGroup. So, you need to access the ExtendedVisualStateManager and VisualStateGroup "ExampleStateGroup" that you have created in the ChildWindow. The only way that I have found to do this (which is somewhat of a hackaround) is to create your own GoToState function that gets called for the state change.

public ExampleWindow()
{
    InitializeComponent();

    MyGoToState("ExampleBaseState");
}

public void MyGoToState(string stateIn)
{

    VisualState stateShow = null;

    VisualStateGroup ExampleStateGroup as VisualStateGroup  

    if(ExampleStateGroup != null)
    {
        for(int i= 0; i < ExampleStateGroup.States.Count; i++)
        {
            stateShow = ExampleStateGroup.States[i] as VisualState;

            if(stateShow != null)
            {

                if(stateShow.Name == stateIn.Trim())
                {
                    stateShow.Storyboard.Begin();
                }

            }

         }
    }
}
Nussbaum answered 22/6, 2014 at 18:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.