WPF/Silverlight:VisualStateManager与触发器?

for*_*yez 13 silverlight wpf xaml

我发现可视状态管理器和触发器之间的功能有一些重叠.

<VisualStateManager.VisualStateGroups>
   <VisualStateGroup x:Name="CommonStates">
      <VisualState x:Name="Pressed">
             ... bla bla ...
      </VisualState>
  </VisualStateGroup>
</VisualStateManager.VisualStateGroups>
Run Code Online (Sandbox Code Playgroud)

或者我可以去

<Trigger Property="IsPressed" Value="true">
          ... bla bla ...
</Trigger>
Run Code Online (Sandbox Code Playgroud)

我何时应该使用一个与另一个?

Ree*_*sey 8

两者之间存在巨大的重叠. VisualStateManager在处理了因使用复杂场景的触发器而产生的"痛苦"之后,我被添加了.通常,它更灵活,更易于使用.


Jos*_*h G 7

使用触发器更容易做一些事情,而使用VSM则更容易.

使用VSM的最大原因是Silverlight不支持触发器.如果您希望过渡到Silverlight,请远离触发器.

VSM的两个缺点:

  • 您无法轻松设置开始状态.最好的方法是将它设置在某个地方的代码中,但这很痛苦.
  • 不建议在两个不同的状态组中设置相同属性的动画,但在实现控件模板时通常需要这样做.您可以使用触发器在状态重叠中获得更多粒度,因为您可以使用多个条件.

VSM似乎是未来.如果您使用Blend,则VSM非常易于配置.


Noi*_*oir 5

为什么要使用VisualStateManager,而不是最终使用触发器?

让我们从它们之间的一般差异开始。

  • 如何解雇他们:
    • 属性更改其时将触发触发器。
    • 控件请求一状态中的一个状态时,将触发VisualStates 。
  • 他们被解雇时执行的操作:
    • 触发条件:
      1. 通过Setter其他财产建立。
    • VisualState
      1. 向发起状态更改请求VisualStateManager
      2. VisualStateManagerVisualTransition在设置状态之前执行。
      3. VisualTransition执行一个Storyboard
      4. 经过GeneratedDuration(of VisualTransition)指定的时间后,VisualStateManager更新控件CurrentState对应的属性VisualStateGroup
      5. 接下来,VisualStateManager执行VisualState(1)中请求的初始值。
      6. 最后,VisualState执行另一个Storyboard

是的,您认为VisualStateManager使方案比触发器更复杂是对的。但是,VisualStateManager的复杂性使程序员可以执行触发器无法做到的事情(不是简单的方式):

  • 区分状态和状态转换:
    • 在状态更改期间生成动画,而与状态本身无关,而无需生成其他额外属性。
    • 通过正确设置FromTo命令允许重复使用相同的过渡VisualTransition
    • 自动控制视觉问题和动画(例如,停止过渡动画并在过渡中间激活另一个动画)。
    • 易于添加/编辑/维护/删除复杂的动画,这有助于在复杂的场景中进行编程。
  • 由于可以通过更改属性,事件,方法等来创建VisualState:,因此提供了更大的自由度。即使使用xaml,也可以Behavior正确使用它,这甚至是最神奇的事情。

  • 同时实现多个状态和状态转换:由于您可以将一组状态组分配给控件(a VisualStateGroup),并且每个状态组CurrentState在给定时间具有唯一性。也许一张图像说得最好: 使用Prism Library 5.0 for WPF的基于状态的导航快速入门

  • 与WPF的自然集成:因为隐式地,控件是处理状态的控件,并允许以某种形式的控件树(父控件)控制状态,这在WPF中是自然发生的。这样,您仅需几行就可以生成非常复杂的方案。当然,也无需触摸控件后面的代码。

而且我很确定还有更多优势。最有趣的是,如果您想使用触发器自己实现其中一些优势,最终您将陷入与VisualStateManager非常相似的系统中……尝试一下!

但是...总是使用VisualStateManager不好

即使具有所有这些优点,VisualStateManager系统也不应丢弃Triggers系统。触发器是一个简单的系统,但也有其潜力。

就个人而言,我将触发器用于非常简单的“原始”控件,这些控件不需要奇怪的行为或奇怪的动画。在此类控件中,VisualStateManager的实现复杂性无法证明其使用的合理性。

对于更复杂的控件,我将使用VisualStateManager,尤其是在那些使用其他“原始”控件的“复杂”控件上(请注意“原始”和“复杂”概念的含义)。当然,根据用户交互,此控件具有复杂的行为。