Begin animation when ContentControl.Content is changed

后端 未结 2 1180
暗喜
暗喜 2021-01-06 08:02

I\'m trying to fire an animation when a content control such as Button or ContentControl changes its content. My initial thoughts were to do this:

        &l         


        
相关标签:
2条回答
  • 2021-01-06 08:40

    There is no CLR-event for ContentChanged (much less a RoutedEvent required for EventTriggers) unfortunately. However, given that you're dealing with a custom control, you can override the metadata for the Content property and provide your own callback within the control.

    This may be about what you're looking for here

    Obviously he's created a CLR-event to propagate content changes externally; you could also do the same just using a RoutedEvent instead.

    Additional reading on OverrideMetadata here

    0 讨论(0)
  • 2021-01-06 08:50

    You can just write an attached property:

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

    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's much easier and shorter than a new control.

    0 讨论(0)
提交回复
热议问题