2017-02-24 41 views
1

在我CustomControl我使用的是VisualStateManager这样的:WPF/XAML VisualStateManager谁处理事件?

... 
<ControlTemplate TargetType="{x:Type local:MyCustomControl}"> 
    <Grid x:Name="rootGrid" > 
     <Grid.RowDefinitions> 
      <RowDefinition Height="65"></RowDefinition> 
      <RowDefinition Height="*"></RowDefinition> 
     </Grid.RowDefinitions> 
     <VisualStateManager.VisualStateGroups> 
      <VisualStateGroup x:Name="CheckStates"> 
       <VisualState x:Name="Checked"> 
        <Storyboard> 
         <DoubleAnimation Storyboard.TargetName="toggleRegionContent" 
             Storyboard.TargetProperty="Height" 
             From="0" 
             To="{TemplateBinding ContentHeight}" 
             Duration="0:0:.7" /> 
         <DoubleAnimation Storyboard.TargetName="arrowIcon" 
             Storyboard.TargetProperty="(Path.RenderTransform).(TransformGroup.Children)[2].(RotateTransform.Angle)" 
             From="0" 
             To="180" 
             Duration="0:0:.1" /> 
         </Storyboard> 
       <VisualState> 
       <!-- Some other States --> 
      </VisualStateGroup> 
     </VisualStateManager> 
    <ToggleButton> 
<!-- The Rest of the Control --> 

我现在的问题是如何经过该事件被处理或谁处理它。 VisualStateManager会在点击ToggleButton时自动切换状态。还是我必须给我的切换按钮选中的事件,并指定按钮的状态,代码像这样的东西的背后:

VisualStateManager.GoToElementState(Control, "Checked", true); 

感谢您的帮助。

回答

1

还是我必须给我的切换按钮选中的事件,并指定按钮的状态,代码像这样的东西的背后:

是的,您的自定义控制负责设置当前使用VisualStateManager类和其GoToState方法的可视状态。

你可以阅读更多有关这在MSDN上:https://msdn.microsoft.com/en-us/library/ee330302(v=vs.110).aspx

+0

代码隐藏方式看起来很干净。在这一点上,我想问你是否可以告诉我哪种方式更清洁:代码隐藏或纯XAML(WBuck的答案) – Febertson

+0

你需要两者。 VisualState是在ControlTemplate的XAML标记中定义的,并且可以在控件类中以编程方式调用VisualStateManager.GoToState方法,以确定控件当前处于哪种状态。在为特定状态调用GoToState方法时,您在XAML中定义的动画会得到应用。 – mm8

+0

我试过WBuck的解决方案,它完美的工作,没有任何代码背后。这就是为什么我要问,如果Code Behind在这种情况下是更清洁的解决方案还是交互触发器更好。对于这类问题,我的XAML/Wpf知识不够高。 – Febertson

1

你必须通过使用该GoToStateAction行为或DataStateBehavior切换状态。

如果只是在2个状态之间切换,那么DataStateBehavior非常好。 如果你想在多个状态之间切换,GoToStateAction很不错。

首先,这里是一个使用DataStateBehavior的非常简单的例子。我点击复选框切换矩形的颜色。

<Grid> 
    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup x:Name="MyStates"> 
      <VisualStateGroup.Transitions> 
       <VisualTransition GeneratedDuration="0:0:0.3" 
            To="Checked"> 
        <VisualTransition.GeneratedEasingFunction> 
         <CubicEase EasingMode="EaseInOut" /> 
        </VisualTransition.GeneratedEasingFunction> 
       </VisualTransition> 
       <VisualTransition GeneratedDuration="0:0:0.3" 
            To="Unchecked"> 
        <VisualTransition.GeneratedEasingFunction> 
         <CubicEase EasingMode="EaseInOut" /> 
        </VisualTransition.GeneratedEasingFunction> 
       </VisualTransition> 
      </VisualStateGroup.Transitions> 
      <VisualState x:Name="Checked"> 
       <Storyboard> 
        <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" 
                Storyboard.TargetName="myRect"> 
         <EasingColorKeyFrame KeyTime="0" 
              Value="#FF6F6FFF" /> 
        </ColorAnimationUsingKeyFrames> 
       </Storyboard> 
      </VisualState> 
      <VisualState x:Name="Unchecked" /> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 
    <i:Interaction.Behaviors> 
     <ei:DataStateBehavior Binding="{Binding IsChecked, ElementName=myCheckBox}" 
           Value="True" 
           TrueState="Checked" 
           FalseState="Unchecked" /> 
    </i:Interaction.Behaviors> 
    <Rectangle x:Name="myRect" 
       Fill="#FFF4F4F5" 
       HorizontalAlignment="Left" 
       Margin="43.166,74.07,0,153.968" 
       Stroke="Black" 
       Width="104.438" /> 
    <CheckBox x:Name="myCheckBox" 
       Content="CheckBox" 
       Height="20.776" 
       Margin="239.69,88.668,192.524,0" 
       VerticalAlignment="Top" /> 

</Grid> 

这里是一个使用GoToStateAction的例子。再次,我只是基于被选中的复选框来改变矩形的颜色。

<Grid> 
    <VisualStateManager.VisualStateGroups> 
     <VisualStateGroup x:Name="MyStates"> 
      <VisualStateGroup.Transitions> 
       <VisualTransition GeneratedDuration="0:0:0.3" 
            To="Checked"> 
        <VisualTransition.GeneratedEasingFunction> 
         <CubicEase EasingMode="EaseInOut" /> 
        </VisualTransition.GeneratedEasingFunction> 
       </VisualTransition> 
       <VisualTransition GeneratedDuration="0:0:0.3" 
            To="Unchecked"> 
        <VisualTransition.GeneratedEasingFunction> 
         <CubicEase EasingMode="EaseInOut" /> 
        </VisualTransition.GeneratedEasingFunction> 
       </VisualTransition> 
      </VisualStateGroup.Transitions> 
      <VisualState x:Name="Checked"> 
       <Storyboard> 
        <ColorAnimationUsingKeyFrames Storyboard.TargetProperty="(Shape.Fill).(SolidColorBrush.Color)" 
                Storyboard.TargetName="myRect"> 
         <EasingColorKeyFrame KeyTime="0" 
              Value="#FF6F6FFF" /> 
        </ColorAnimationUsingKeyFrames> 
       </Storyboard> 
      </VisualState> 
      <VisualState x:Name="Unchecked" /> 
     </VisualStateGroup> 
    </VisualStateManager.VisualStateGroups> 
    <Rectangle x:Name="myRect" 
       Fill="#FFF4F4F5" 
       HorizontalAlignment="Left" 
       Margin="43.166,74.07,0,153.968" 
       Stroke="Black" 
       Width="104.438" /> 
    <CheckBox x:Name="myCheckBox" 
       Content="CheckBox" 
       Height="20.776" 
       Margin="239.69,88.668,192.524,0" 
       VerticalAlignment="Top"> 
     <i:Interaction.Triggers> 
      <ei:DataTrigger Binding="{Binding IsChecked, ElementName=myCheckBox}" 
          Value="True"> 
       <ei:GoToStateAction StateName="Checked" /> 
      </ei:DataTrigger> 
      <ei:DataTrigger Binding="{Binding IsChecked, ElementName=myCheckBox}" 
          Value="False"> 
       <ei:GoToStateAction StateName="Unchecked" /> 
      </ei:DataTrigger> 
     </i:Interaction.Triggers> 
    </CheckBox> 

</Grid> 

编辑: 确保您引用添加到混合SDK用于上述方法的工作。

xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions" 
+0

感谢您的长答案和代码片段。但我不知道,如果XAML答案比代码隐藏解决方案更清洁。 – Febertson

+0

你的答案也适用,但在我的意见中,mm8提供的答案看起来更清晰。但是,感谢这个解决方案。它有助于理解VisualStateManager。 – Febertson