2017-08-24 111 views
0

我有一个模板ToggleButton看起来像这样:如何添加自定义绑定的切换按钮动画

<Window.Resources> 
     <Style TargetType="ToggleButton"> 
      <Setter Property="Foreground" Value="#58585a"/> 
      <Setter Property="Padding" Value="3"/> 
      <Setter Property="BorderThickness" Value="1"/> 
      <Setter Property="BorderBrush" Value="#58585a"> 
      </Setter> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="ToggleButton"> 
         <Grid> 
          <VisualStateManager.VisualStateGroups> 
           <VisualStateGroup x:Name="CommonStates"> 
            <VisualState x:Name="Normal"/> 
            <VisualState x:Name="MouseOver"/> 
            <VisualState x:Name="Pressed"/> 
            <VisualState x:Name="Disabled"/> 
           </VisualStateGroup> 
           <VisualStateGroup x:Name="CheckStates"> 
            <VisualState x:Name="Checked"> 
             <Storyboard> 
              <ColorAnimation To="Green" Storyboard.TargetName="BackgroundGrid" Storyboard.TargetProperty="(Background).(SolidColorBrush.Color)" /> // Bind the color to BackgroundChecked 
              <ColorAnimation To="White" Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="(TextBlock.Foreground).(SolidColorBrush.Color)"/> // Bind the color to ForegroundChecked 
             </Storyboard> 
            </VisualState> 
            <VisualState x:Name="Unchecked"/> 
           </VisualStateGroup> 
           <VisualStateGroup x:Name="FocusStates"> 
            <VisualState x:Name="Unfocused" /> 
           </VisualStateGroup> 
          </VisualStateManager.VisualStateGroups> 
          <Border x:Name="Background" BorderThickness="{TemplateBinding BorderThickness}" BorderBrush="{TemplateBinding BorderBrush}"> 
           <Grid x:Name="BackgroundGrid" Background="Transparent" Margin="1"/> 
          </Border> 
          <ContentPresenter x:Name="contentPresenter" Content="{TemplateBinding Content}" ContentTemplate="{TemplateBinding ContentTemplate}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" Margin="{TemplateBinding Padding}"/> 
         </Grid> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </Window.Resources> 

我想在经过的VisualState编辑ColorAnimation,以便使用ToggleButton这样:

<ToggleButton BackgroundChecked="Green" ForegroundChecked="White">Green</ToggleButton> 

实现该目标的方法是什么?

编辑:

我模板我自己ToggleButton和定义自己的DependencyProperty这样的:

<ToggleButton x:Name="root" x:Class="WpfApplicationTest.ToggleButtonColor" 
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:local="clr-namespace:WpfApplicationTest" 
      mc:Ignorable="d" 
      d:DesignHeight="40" d:DesignWidth="100"> 
    <ToggleButton.Template> 
     <ControlTemplate 
       TargetType="{x:Type ToggleButton}"> 
      <Grid> 
       <VisualStateManager.VisualStateGroups> 
        <VisualStateGroup x:Name="CommonStates"> 
         <VisualState x:Name="Normal" /> 
         <VisualState x:Name="MouseOver"/> 
         <VisualState x:Name="Pressed" /> 
         <VisualState x:Name="Disabled"/> 
        </VisualStateGroup> 
        <VisualStateGroup x:Name="CheckStates"> 
         <VisualState x:Name="Checked"> 
          <Storyboard> 
           <ColorAnimation To="{Binding BackgroundChecked, ElementName=root}" Storyboard.TargetName="BackgroundBrush" Storyboard.TargetProperty="Color" /> 
          </Storyboard> 
         </VisualState> 
         <VisualState x:Name="Unchecked" /> 
         <VisualState x:Name="Indeterminate" /> 
        </VisualStateGroup> 
       </VisualStateManager.VisualStateGroups> 
       <Border x:Name="Border" BorderThickness="1" BorderBrush="#58585a"> 
        <Border.Background> 
         <SolidColorBrush x:Name="BackgroundBrush" Color="Transparent"/> 
        </Border.Background> 
       </Border> 
       <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" TextBlock.Foreground="#58585a" TextBlock.FontSize="12"/> 
      </Grid> 
     </ControlTemplate> 
    </ToggleButton.Template> 
</ToggleButton> 

这:

public Color BackgroundChecked 
     { 
      get { return (Color)GetValue(BackgroundCheckedProperty); } 
      set { SetValue(BackgroundCheckedProperty, value); } 
     } 

     // Using a DependencyProperty as the backing store for BackgroundChecked. This enables animation, styling, binding, etc... 
     public static readonly DependencyProperty BackgroundCheckedProperty = 
      DependencyProperty.Register("BackgroundChecked", typeof(Color), typeof(ToggleButton)); 

当我尝试使用此:

<local:ToggleButtonColor BackgroundChecked="Red" BorderBrush="#58585a" BorderThickness="1" Width="100" Height="50" Content="test"></local:ToggleButtonColor> 

我有这样的错误:

System.Windows.Data Error: 2 : Cannot find governing FrameworkElement or FrameworkContentElement for target element. BindingExpression:Path=BackgroundChecked; DataItem=null; target element is 'ColorAnimation' (HashCode=27433049); target property is 'To' (type 'Nullable`1') 
+0

他们尚未确定,我想我已经定义的DependencyProperty,但我不知道怎么。目标是让一个带有6个ToggleButton的StackPanel将每一个与一个颜色相关联。 –

+0

那么你的问题是什么?如何定义依赖项属性?你应该缩小你的问题一点。 – mm8

+0

@ mm8我花了一些时间来审查我的问题,并编辑我的问题以添加更精确的示例。现在,我有约束力,但不起作用。 –

回答

0

因为动画被冻结由于性能原因,您不能绑定到一个ColorAnimationTo属性:https://social.msdn.microsoft.com/Forums/vstudio/en-US/027c364f-5d75-424f-aafd-7fb76b10b676/templatebinding-on-storyboard?forum=wpf

你可以参考以下类似的问题一些建议:

WPF animation: binding to the "To" attribute of storyboard animation

代替试图在XAML绑定,你也可以以编程方式创建动画:

public class ToggleButtonColor : ToggleButton 
{ 
    public Color BackgroundChecked 
    { 
     get { return (Color)GetValue(BackgroundCheckedProperty); } 
     set { SetValue(BackgroundCheckedProperty, value); } 
    } 

    public static readonly DependencyProperty BackgroundCheckedProperty = 
     DependencyProperty.Register("BackgroundChecked", typeof(Color), typeof(ToggleButton)); 

    public ToggleButtonColor() 
    { 
     Checked += MyToggleButton_Checked; 
    } 

    private void MyToggleButton_Checked(object sender, RoutedEventArgs e) 
    { 
     ColorAnimation colorAnimation = new ColorAnimation(); 
     colorAnimation.To = BackgroundChecked; 
     Storyboard.SetTarget(colorAnimation, this); 
     Storyboard.SetTargetProperty(colorAnimation, new PropertyPath("Background.Color")); 
     Storyboard sb = new Storyboard(); 
     sb.Children.Add(colorAnimation); 
     sb.Begin(); 
    } 
} 

XAML:

<local:ToggleButtonColor Content="test" BackgroundChecked="Red"> 
    <local:ToggleButtonColor.Style> 
     <Style TargetType="local:ToggleButtonColor"> 
      <Setter Property="Background" Value="Transparent" /> 
      <Setter Property="Template"> 
       <Setter.Value> 
        <ControlTemplate TargetType="local:ToggleButtonColor"> 
         <Border x:Name="Border" BorderThickness="1" BorderBrush="#58585a" Background="{TemplateBinding Background}"> 
          <ContentPresenter VerticalAlignment="Center" HorizontalAlignment="Center" TextBlock.Foreground="#58585a" TextBlock.FontSize="12"/> 
         </Border> 
        </ControlTemplate> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </local:MyToggleButton.Style> 
</local:MyToggleButton> 
+0

感谢您的帮助! –