c# - 代码隐藏中的 WPF UserControl 动画不适用于 ContentPresenter

标签 c# wpf xaml animation

当代码是这样的时候,动画工作如预期。

AnimatedUserControl2.xaml

<UserControl x:Class="WpfPoc20120908.AnimatedUserControl2"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" IsVisibleChanged="AnimatedUserControl2_OnIsVisibleChanged">
    <Grid Background="Coral">
        <Canvas>
            <TextBlock x:Name="MNB" Text="ABCD"/>
        </Canvas>
    </Grid>
</UserControl>

AnimatedUserControl2.xaml.cs(仅部分代码)

        private void AnimatedUserControl2_OnIsVisibleChanged(object sender, DependencyPropertyChangedEventArgs e)
        {
            if (Visibility == Visibility.Visible)
            {
                var storyboard = new Storyboard();
                var visibilityAnimation = new ObjectAnimationUsingKeyFrames();
                visibilityAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame(Visibility.Visible,
                                                                             KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0))));
                Storyboard.SetTargetProperty(visibilityAnimation, new PropertyPath(VisibilityProperty));
                storyboard.Children.Add(visibilityAnimation);
                var opacityAnimation = new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(1)));
                Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(OpacityProperty));
                storyboard.Children.Add(opacityAnimation);
                var canvasLeftAnimation = new DoubleAnimationUsingKeyFrames();
                canvasLeftAnimation.KeyFrames.Add(new LinearDoubleKeyFrame(200,
                                                                           KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0))));
                canvasLeftAnimation.KeyFrames.Add(new SplineDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1)),
                                                                           new KeySpline(new Point(0.25, 0.1),
                                                                                         new Point(0.25, 1))));
                Storyboard.SetTargetProperty(canvasLeftAnimation, new PropertyPath(Canvas.LeftProperty));
                storyboard.Children.Add(canvasLeftAnimation);
                MNB.BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, false);
            }
        }

但是,当我在 XAML 代码中使用 ContentPresenter 时,动画根本不起作用

AnimationUserControl2.xaml(第一次修订)

<UserControl x:Class="WpfPoc20120908.AnimatedUserControl2"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" IsVisibleChanged="AnimatedUserControl2_OnIsVisibleChanged">
    <Grid Background="Coral">
        <Canvas>
            <ContentPresenter x:Name="MNB"/>
        </Canvas>
    </Grid>
</UserControl>

当我尝试用网格包裹 ContentPresenter 时,动画仍然不起作用

AnimationUserControl2.xaml(第二次修订)

<UserControl x:Class="WpfPoc20120908.AnimatedUserControl2"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300" IsVisibleChanged="AnimatedUserControl2_OnIsVisibleChanged">
    <Grid Background="Coral">
        <Canvas>
            <Grid x:Name="MNB">
                <ContentPresenter/>
            </Grid>
        </Canvas>
    </Grid>
</UserControl>

问题来了。 如何让动画与 ContentPresenter 配合使用?

更新 01

AnimatedUserControl2 的使用方法如下。

MainWindow.xaml(仅部分代码)

        <StackPanel Grid.Row="0" Orientation="Vertical">
            <usercontrols:AnimatedUserControl2 x:Name="ABCD" Visibility="Hidden">
                <TextBlock Text="ABC"/>
            </usercontrols:AnimatedUserControl2>
            <usercontrols:AnimatedUserControl2 x:Name="EFGH" Visibility="Hidden" Margin="10">
                <TextBlock Text="ABC"/>
            </usercontrols:AnimatedUserControl2>
        </StackPanel>
        <Button x:Name="ButtonBeginAnimation" Click="ButtonBeginAnimation_OnClick" Content="Begin Animation" Grid.Row="1"/>

MainWindow.xaml.cs(仅部分代码)

        private void ButtonBeginAnimation_OnClick(object sender, RoutedEventArgs e)
        {
            ABCD.Visibility = (ABCD.Visibility == Visibility.Visible) ? Visibility.Collapsed : Visibility.Visible;
            EFGH.Visibility = (EFGH.Visibility == Visibility.Visible) ? Visibility.Collapsed : Visibility.Visible;
        }

最佳答案

所以问题在于您如何使用您的用户控件 - 一旦在 UserControl xaml 定义中指定,您只需覆盖内容...无论如何.. 试试这个方法(动画在我的机器上工作所以假设在你的机器上也能工作;))

<UserControl x:Class="WpfApplication11.UserControl1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
         d:DesignHeight="300"
         d:DesignWidth="300"
         mc:Ignorable="d">
<UserControl.Template>
    <ControlTemplate TargetType="UserControl">
        <Grid Background="Coral">
            <Canvas>
                <ContentPresenter x:Name="MNB" Content="{TemplateBinding Content}"/>
            </Canvas>
        </Grid>
    </ControlTemplate>
</UserControl.Template>

在动画本身中:

  private void AnimatedUserControl2_OnIsVisibleChanged(object sender, EventArgs e)
    {
        var mnb = Template.FindName("MNB", this) as FrameworkElement;
        if (mnb == null)
        {
            return;
        }

        if (Visibility == Visibility.Visible)
        {
            var storyboard = new Storyboard();
            var visibilityAnimation = new ObjectAnimationUsingKeyFrames();
            visibilityAnimation.KeyFrames.Add(new DiscreteObjectKeyFrame(Visibility.Visible,
                                                                         KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0))));
            Storyboard.SetTargetProperty(visibilityAnimation, new PropertyPath(VisibilityProperty));
            storyboard.Children.Add(visibilityAnimation);
            var opacityAnimation = new DoubleAnimation(0, 1, new Duration(TimeSpan.FromSeconds(1)));
            Storyboard.SetTargetProperty(opacityAnimation, new PropertyPath(OpacityProperty));
            storyboard.Children.Add(opacityAnimation);
            var canvasLeftAnimation = new DoubleAnimationUsingKeyFrames();
            canvasLeftAnimation.KeyFrames.Add(new LinearDoubleKeyFrame(200,
                                                                       KeyTime.FromTimeSpan(TimeSpan.FromSeconds(0))));
            canvasLeftAnimation.KeyFrames.Add(new SplineDoubleKeyFrame(0, KeyTime.FromTimeSpan(TimeSpan.FromSeconds(1)),
                                                                       new KeySpline(new Point(0.25, 0.1),
                                                                                     new Point(0.25, 1))));
            Storyboard.SetTargetProperty(canvasLeftAnimation, new PropertyPath(Canvas.LeftProperty));
            storyboard.Children.Add(canvasLeftAnimation);
            mnb.BeginStoryboard(storyboard, HandoffBehavior.SnapshotAndReplace, false);
        }
    }

关于c# - 代码隐藏中的 WPF UserControl 动画不适用于 ContentPresenter,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19336037/

相关文章:

c# - 如何获取小部件的索引以及为什么它只给出第一个值

WPF 字体缩放

c# - 动态生成时如何检索已单击的按钮

c# - UWP 中的 ListView

c# - Windows 8 应用程序上的全局应用程序栏

c# - 使用两个日期选择器控件来指定开始和结束日期?

c# - 如何在 Angular 和 Asp.Net Boilerplate 上获取当前用户 ID?

c# - 找不到 ASP.NET 母版页

wpf - 如何在WPF中绑定(bind)的StringFormat中使用引号

c# - 避免 Uris 上的数据库信息