C# 更改ContentControl.Content时开始动画
我试图在内容控件(如Button或ContentControl)更改其内容时触发动画。我最初的想法是这样做:C# 更改ContentControl.Content时开始动画,c#,wpf,xaml,C#,Wpf,Xaml,我试图在内容控件(如Button或ContentControl)更改其内容时触发动画。我最初的想法是这样做: <ContentControl x:Name="ContentElement"> <ContentControl.Style> <Style TargetType="ContentControl"> <Setter Property="
<ContentControl x:Name="ContentElement">
<ContentControl.Style>
<Style TargetType="ContentControl">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ContentControl">
<ContentPresenter x:Name="Content">
<ContentPresenter.Triggers>
<EventTrigger RoutedEvent="WHATGOESHERE">
<BeginStoryboard Storyboard="{StaticResource MyAnimation}" Storyboard.TargetName="Content"/>
</EventTrigger>
</ContentPresenter.Triggers>
</ContentPresenter>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ContentControl.Style>
<Button Content="Hello"/>
</ContentControl>
但我不知道更改/更新ContentPresenter时会触发哪个事件。有什么想法吗?不幸的是,ContentChanged没有CLR事件(更不用说EventTriggers需要RoutedEvent了)。但是,如果您处理的是自定义控件,则可以重写Content属性的元数据,并在控件内提供自己的回调 这可能是你想要的 很明显,他创建了一个CLR事件来对外传播内容更改;您也可以使用RouteEvent来执行相同的操作
关于OverrideMetadata的附加阅读您只需编写一个附加属性:
using System;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Animation;
static class ContentControlExtensions
{
public static readonly DependencyProperty ContentChangedAnimationProperty = DependencyProperty.RegisterAttached(
"ContentChangedAnimation", typeof(Storyboard), typeof(ContentControlExtensions), new PropertyMetadata(default(Storyboard), ContentChangedAnimationPropertyChangedCallback));
public static void SetContentChangedAnimation(DependencyObject element, Storyboard value)
{
element.SetValue(ContentChangedAnimationProperty, value);
}
public static Storyboard GetContentChangedAnimation(DependencyObject element)
{
return (Storyboard)element.GetValue(ContentChangedAnimationProperty);
}
private static void ContentChangedAnimationPropertyChangedCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)
{
var contentControl = dependencyObject as ContentControl;
if (contentControl == null)
throw new Exception("Can only be applied to a ContentControl");
var propertyDescriptor = DependencyPropertyDescriptor.FromProperty(ContentControl.ContentProperty,
typeof (ContentControl));
propertyDescriptor.RemoveValueChanged(contentControl, ContentChangedHandler);
propertyDescriptor.AddValueChanged(contentControl, ContentChangedHandler);
}
private static void ContentChangedHandler(object sender, EventArgs eventArgs)
{
var animateObject = (FrameworkElement) sender;
var storyboard = GetContentChangedAnimation(animateObject);
storyboard.Begin(animateObject);
}
}
然后在XAML中:
<ContentControl Content="{Binding SelectedViewItem}">
<extensions:ContentControlExtensions.ContentChangedAnimation>
<Storyboard>
<ThicknessAnimation To="0" From="30,0,-30,0" Duration="0:0:0.3" Storyboard.TargetProperty="Margin"/>
</Storyboard>
</extensions:ContentControlExtensions.ContentChangedAnimation>
</ContentControl>
它比新控件更简单、更短。如果更改
Get..
中的DependencyObject
调用,并将…
方法设置为ContentControl
,则不需要在回调方法中进行类型检查。很好的示例,非常简单……对于新的WPF开发人员来说,在XAML的顶部添加xmlns:behavior=“clr namespace:”……这不是一个行为,而是一个附加属性。非常简单的示例,最好的答案在这里。