silverlight - Silverlight 中的 VisualStateManager : setting an initial state

标签 silverlight expression-blend visualstatemanager

我经常发现需要包含“离开”和“当前”类型的视觉状态,这些状态用于根据其他条件设置控件离开或可见的动画。

“离开”状态通常应该是初始状态。据我了解,没有办法在 SL 中定义初始状态,而是“base”,它根本不是一个真正的状态,而是表示状态管理器尚未激活时的外观(没有状态 Storyboard正在运行更改控件的外观)。

当然,您可以将“基础”设计为看起来像“离开”,但这意味着 Expression Blend 中的默认外观是不可见的(您也不能永久“固定”状态)。

为了改变我试过的初始状态

  • 在控件的ctor中设置状态,它什么都不做,
  • 在 ctor 或 Loaded 事件的分派(dispatch)调用中设置状态,它们都在瞬间显示错误的状态。

  • 所以问题似乎是无论视觉状态管理器做什么,它都不会立即执行,而是需要一个明显的瞬间来改变外观。

    (当然,直接为 bootstrap 设置属性是另一种选择,但仅适用于 UserControls:在模板化控件中,我必须引入另一个 depprop 来模板绑定(bind)控件模板,我认为这是矫枉过正的开始。)

    我想我已经涵盖了所有内容,而我只需要忍受一个看不见的基本状态吗?

    我用的是 SL4。

    最佳答案

    我在开发 时遇到了类似的问题用户控制 用于 Expression Blend 中的 WPF(注意:如果您正在开发自定义控件,请参阅我的下一部分)。在那个 UserControl 中,我有一个子元素,我想淡入并成长为覆盖层。像您的情况一样,在我的工作流程中,首先将覆盖元素设计为“完全增长和可见”状态,然后将其缩小并将其不透明度设置为“隐藏”状态是有意义的。在执行此操作时,覆盖在 Base 状态下可见,但我需要 UserControl 的初始状态为 Hidden 状态。在这一点上,我有三个主要的相关状态:基本、“隐藏”和“可见”(最后两个是状态组的一部分)。

    以下是我解决初始状态问题的方法 .首先,我将 GoToStateAction 应用于由 Loaded 事件触发的根元素(到 UserControl)。它告诉 UserControl 直接进入“隐藏”状态:

    enter image description here

    <i:Interaction.Triggers>
      <i:EventTrigger>
        <ei:GoToStateAction TargetObject="{Binding ElementName=userControl}" StateName="Hidden"/>
      </i:EventTrigger>
    </i:Interaction.Triggers>
    

    其次,我在 State Group 中为叠加层进行了适当的过渡设置。可能有几种方法可以做到这一点,但我是这样做的。首先,我将“默认过渡”设置为令人愉悦的设置,例如 0.4 秒。接下来,我将任何元素(Blend 中的星形图标)到此“隐藏”状态的转换时间设置为 0 秒(这允许上述 GoToStateAction 设置“初始”状态而用户不知道任何不同)。然后,我将“可见”状态到“隐藏”状态的转换设置为适当的设置(例如 0.4 秒)。基本上,这涵盖了过渡的所有基础。关键是确保从“任何元素”到“隐藏”状态的“转换”是立即的,然后在从覆盖的“可见”状态到“隐藏”状态的情况下覆盖该立即转换。

    enter image description here

    设置 的初始 VisualState自定义控件

    如果您正在开发自定义控件(而不是 UserControl)并因此在控件模板中定义 VisualStateManager,则上述方法(基于 Loaded 事件启动 VisualState 更改)可能不起作用。这是因为控件的可视化树(在样式文件中定义)在 OnApplyTemplate() 之前应用到控件。 override 被调用,通常在第一个 Loaded 之后事件已触发。因此,如果您尝试启动 VisualState 更改以响应自定义控件的 Loaded 事件,很可能不会发生任何事情。 相反,您需要在 OnApplyTemplate() 中启动状态更改。 覆盖代码:
    public class MyCustomControl : ContentControl
    {
        // ... other code ....
    
    
        public MyCustomControl()
        {
            // avoid designer errors
            if (DesignerProperties.GetIsInDesignMode(this))
                return;
    
            Loaded += new RoutedEventHandlerMyCustomControl_Loaded);
        }
    
        // This probably won't be called until AFTER OnApplyTemplate() gets
        //  called, so don't expect for your control to even have a visual tree
        //  yet when your control is first being contructed at runtime.
        private void MyCustomControl_Loaded(object sender, RoutedEventArgs e)
        {
    
        }
    
        public override void OnApplyTemplate()
        {
            // Avoid Visual Studio 2010 designer exceptions
            // (Visual Studio can't handle the VisualState change at design-time)
            if (DesignerProperties.GetIsInDesignMode(this))
                return;
    
            base.OnApplyTemplate();
    
            // Now we know that the template has been applied, we have a visual tree,
            //  so state changes will work
            VisualStateManager.GoToState(this, "MyInitialState", false);
        }
    }
    

    关于silverlight - Silverlight 中的 VisualStateManager : setting an initial state,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9521086/

    相关文章:

    c++ - C++ 中的 VisualState 示例?

    c# - 从代码隐藏定义 VisualStates

    silverlight - Siliverlight 数据绑定(bind)组合框不显示初始化值

    c# - wp7 芒果中的 DataTemplateSelector

    silverlight - 我在 MVVM 模型中使用 silverlight 两种方式绑定(bind)获得 Null 对象

    silverlight - 为 Silverlight 行为自动调用 OnDetaching()

    wpf - 在 Expression Blend 中重用设计数据?

    silverlight - 在 Silverlight 中自动更改 VisualState

    wpf - 样式 WPF/Silverlight 组合框

    wpf - 使用 MVVM Light Toolkit 制作可混合应用程序