如何在 ToggleButton 动画上添加自定义绑定
How to add custom binding on ToggleButton 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>
我想在 Checked 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')
您无法绑定到 ColorAnimation
的 To
属性,因为出于性能原因动画被冻结: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>
我有一个 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>
我想在 Checked 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')
您无法绑定到 ColorAnimation
的 To
属性,因为出于性能原因动画被冻结: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>