如何在 ChildWindow 中使用 VisualStates?

发布于 2024-08-19 08:36:51 字数 2586 浏览 6 评论 0原文

有没有办法将 VisualStateManager 与我的 ChildWindow 子类一起使用?对 VisualStateManager 的调用没有任何作用,我所做的谷歌搜索暗示实现此目的的唯一方法是手动调用 Storyboard。这太草率了,而且容易出错。有没有人找到实现它的方法?

更新了示例代码。要使用它,只需创建一个新的 Silverlight 项目,然后通过单击主页上的按钮调用 ExampleWindow.ShowWindow() 即可。即使构造函数设置了应该隐藏按钮的状态,您也会看到该按钮。

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>

隐藏代码 (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();
        }
    }
}

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();
        }
    }
}

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

萤火眠眠 2024-08-26 08:36:52

我遇到了与 Dov 一样的 VSM 无法在 ChildWindows 中工作的问题。
我所做的是将我的 ChildWindow 更改为 UserControl,然后将 UserControl 设置为通用 ChildWindow 的内容,然后再打开它。

var childWindow = new ChildWindow { Content = someUserControl };

现在的问题是您失去了 ChildWindow 类的 DialogResult 功能,因为您的代码行为将位于 UserControl 中。
访问 ChildWindow 的 DialogResult 属性的最简单方法是仅使用 UserControl 内部的 Parent 属性。

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.

还给你自由 2024-08-26 08:36:52

ChildWindow 模板包含一个 VisualStateManager,用于管理常见子窗口动画的 VisualStateGroup“CommonStates”。当您调用 VisualStateManager.GoToState 时,它​​会在 ChildWindow 模板 CommonStates VisualStateGroup 中查找状态。因此,您需要访问您在 ChildWindow 中创建的 ExtendedVisualStateManager 和 VisualStateGroup“ExampleStateGroup”。我发现执行此操作的唯一方法(这有点像黑客)是创建您自己的 GoToState 函数,该函数会被调用以进行状态更改。

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();
                }

            }

         }
    }
}

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();
                }

            }

         }
    }
}
可遇━不可求 2024-08-26 08:36:51

到目前为止,我发现的唯一解决方法是将任何需要视觉状态的内容放入用户控件中。 UserControl 可以具有状态,并可以在它们之间成功切换,并通过事件、方法和属性向 ChildWindow 传达任何必要的信息。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文