2

这个问题是我之前的问题以及关于如何在 WPF 中工作的相关问题的后续问题。VisualStates

目前,我的理解是在不同的属性中为相同的属性设置动画VisualStateGroups可能会导致问题(请参阅链接的问题)。

要解决这些问题,就需要利用漏洞。 (也许漏洞不是正确的术语,但该解决方案似乎不是 WPF 设计者想要的。)

我想知道在VisualStateGroups不引起不良副作用的情况下,为同一属性设置多个动画的正确方法是什么。如果不可能,为控件实现相同视觉行为的正确途径是什么?

我能够在MSDN找到一些相关文档:

每组控件始终处于一个状态。例如,即使鼠标指针不在 Button 上方,它也可以具有焦点,因此处于 Focused 状态的 Button 可以处于 MouseOver、Pressed 或 Normal 状态。

这就引出了第二个问题……

VisualStates您如何提供仅在两个特定活动时才应该发生的视觉行为?

以一个为例ToggleButton

  • 如果按钮是Checked,我想显示Behavior 1
  • 如果按钮是Disabled,我想显示Behavior 2
  • 最后,如果按钮是CheckedDisabled,我想显示Behavior 3

在上面的示例中,您将如何渲染第三个视觉行为?

4

1 回答 1

3

对于问题的第一部分,例如,您将希望每个状态与每个状态的不同单个对象交互,而不是使用每个 VisualState 击中相同的对象;

    <VisualState x:Name="Disabled">
      <Storyboard>
          <ObjectAnimationUsingKeyFrames Storyboard.TargetName="DisabledState" 
                                  Storyboard.TargetProperty="(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
          </ObjectAnimationUsingKeyFrames>
       </Storyboard>
    </VisualState>
    <VisualState x:Name="Checked">
      <Storyboard>
          <ObjectAnimationUsingKeyFrames Storyboard.TargetName="CheckedState" 
                                  Storyboard.TargetProperty="(UIElement.Visibility)">
            <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
          </ObjectAnimationUsingKeyFrames>
       </Storyboard>
    </VisualState>

<!-- Each state interacts with its own object in your ControlTemplate ideally -->
<Border x:Name="CheckedState" Visibility="Collapsed"
        Background="Green"/>
<Border x:Name="DisabledState" Visibility="Collapsed"
        Background="White" Opacity=".5"/>

而不是一个对象共享属性更改,例如;

<VisualState x:Name="Disabled">
  <Storyboard>
      <ColorAnimation d:IsOptimized="True"
                      Duration="0"
                      Storyboard.TargetName="Background"
                      Storyboard.TargetProperty="(SolidColorBrush.Color)"
                      To="White" />
   </Storyboard>
</VisualState>
<VisualState x:Name="Checked">
  <Storyboard>
      <ColorAnimation d:IsOptimized="True"
                      Duration="0"
                      Storyboard.TargetName="Background"
                      Storyboard.TargetProperty="(SolidColorBrush.Color)"
                      To="Green" />
   </Storyboard>
</VisualState>

<Border x:Name="Background" Background="Blue"/>

根据您的第二个问题, AVisualState将充当布尔值,因为它要么处于该状态,要么不处于该状态。要共享状态声明,您必须在某处使用 MultiTrigger 或转换器或其他东西添加更多技巧。

希望这可以帮助。干杯

编辑补充:

所以你也可以VisualTransition使用你喜欢的;

 <VisualStateManager.VisualStateGroups>
  <VisualStateGroup x:Name="CommonStates">
    <VisualStateGroup.Transitions>
      <VisualTransition From="Normal"
        GeneratedDuration="0:0:0.2"
        To="Checked">
        <VisualTransition.GeneratedEasingFunction>
          <ExponentialEase EasingMode="EaseIn" Exponent="7" />
        </VisualTransition.GeneratedEasingFunction>
      </VisualTransition>
      <VisualTransition From="Checked"
        GeneratedDuration="0:0:0.2"
        To="Normal">
        <VisualTransition.GeneratedEasingFunction>
          <CircleEase EasingMode="EaseIn" />
        </VisualTransition.GeneratedEasingFunction>
      </VisualTransition>
    </VisualStateGroup.Transitions>
    <VisualState x:Name="Normal" />
    <!-- etc, etc, etc -->

因此,您可以使用不同的缓动、生成的持续时间等。

于 2014-09-12T16:41:53.343 回答