代码之家  ›  专栏  ›  技术社区  ›  Dov

如何在儿童窗口中使用可视状态?

  •  1
  • Dov  · 技术社区  · 15 年前

    是否有任何方法可以将VisualStateManager与ChildWindow子类一起使用?调用VisualStateManager什么也不做,而我所做的谷歌搜索暗示了实现这一点的唯一方法是手动调用故事板。这太马虎了,容易出错。有人找到了实现它的方法吗?

    用示例代码更新 . 要使用它,只需创建一个新的Silverlight项目,并通过单击主页上的按钮调用exampleWindow.showWindow()。您将看到按钮,即使构造函数设置了隐藏按钮的状态。

    XAML(示例window.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>
    

    代码隐藏(例如window.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();
            }
        }
    }
    
    4 回复  |  直到 10 年前
        2
  •  0
  •   Dov    15 年前

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

        3
  •  0
  •   Manuel R.    15 年前

    我也遇到过同样的问题:vsm没有像dov那样在ChildWindows中工作。 我所做的是将ChildWindow更改为UserControl,然后在打开它之前将UserControl设置为通用ChildWindow的内容。

    var childWindow = new ChildWindow { Content = someUserControl };
    

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

        4
  •  0
  •   bradburdge    10 年前

    ChildWindow模板包含一个VisualStateManager,用于管理常见子窗口动画的VisualStateGroup“CommonStates”。调用VisualStateManager.GoToState时,它正在ChildWindow模板CommonStates VisualStateGroup中查找状态。因此,您需要访问在ChildWindow中创建的扩展的VisualStateManager和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();
                    }
    
                }
    
             }
        }
    }