Start animation when ContentControl.Content changes

I am trying to start an animation when a content control such as Button or ContentControl changes its content. My initial thoughts were as follows:

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

But I do not know which event is triggered when ContentPresenter changes / updates. Any ideas?

+4
source share
2 answers

Unfortunately, there is no CLR event for ContentChanged (moreover, RouteEvent is required for EventTriggers). However, given that you are dealing with a custom control, you can override the metadata for the Content property and provide your own callback in the control.

It might be something you are looking for here.

Obviously, he created a CLR event to propagate content changes from the outside; you can also do the same just using a RoutedEvent.

Further reading of OverrideMetadata here

+1
source

You can simply write an attached property:

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

and then in 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> 

It is much simpler and shorter than the new control.

+9
source

Source: https://habr.com/ru/post/1415333/


All Articles