2017-08-24 2 views
0

J'ai un modèle pour ToggleButton qui ressemble à ceci:Comment ajouter des instructions de liaison sur l'animation 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> 

Je veux modifier le ColorAnimation dans le VisualState vérifié de façon à utiliser le ToggleButton ainsi:

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

Quel est le moyen d'y parvenir?

Edit:

Je suis basé sur un modèle ma propre ToggleButton et définit sa DependencyProperty comme ceci:

<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> 

et ceci:

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)); 

Quand j'essaie d'utiliser ceci:

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

J'ai cette erreur:

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

Ils ne sont pas encore définis, je pense que je dois définir DependencyProperty mais je ne savoir comment. Le but est d'avoir un StackPanel avec 6 ToggleButton associés chacun à une couleur. –

+0

Alors, quelle est votre question? Comment définir une propriété de dépendance? Vous devriez affiner votre question un peu. – mm8

+0

@ mm8 J'ai pris le temps de revoir mon problème et d'éditer ma question pour ajouter un exemple plus précis. Maintenant, j'ai la liaison mais ça ne marche pas. –

Répondre

0

Vous ne pouvez pas lier à la propriété To d'un ColorAnimation parce que l'animation est gelé pour des raisons de performance: https://social.msdn.microsoft.com/Forums/vstudio/en-US/027c364f-5d75-424f-aafd-7fb76b10b676/templatebinding-on-storyboard?forum=wpf

Vous pouvez se référer à la question similaire suivante pour quelques suggestions:

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

Au lieu de en essayant de se lier en XAML, vous pouvez également créer l'animation par programmation:

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

Merci pour l'aide! –