2013-10-12 7 views
2

Когда код похож на этот, анимация работает, как и ожидалось.WPF UserControl Анимация в коде не работает с ContentPresenter

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 (Partial код только)

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

Однако, когда я использую ContentPresenter в коде XAML, анимацию не работает вообще.

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?

UPDATE 01

Вот как используется AnimatedUserControl2.

MainWindow.xaml (Partial код только)

 <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 (Partial код только)

 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; 
     } 
+0

Вы используете UserControl с ведущим контентом в нем, что кажется странным .. Как вы кладете ваше содержание UserControl? Можете ли вы показать некоторый код xam, в котором фактически используется AnimatedUserControl2? –

+0

Привет, @ SebastianÐymel. Я уточнил вопрос более подробно. В основном, я указываю контент в коде XAML. Это похоже на то, как я указываю содержимое панельных элементов управления (например, Grid). – Louie

ответ

1

Так что проблема с тем, как вы используете ваш пользовательский контроль - вы просто переопределяете содержимое, определенное в определении UserControl xaml ... в любом случае .. Попробуйте этот подход (анимация работает на моей машине, поэтому предположим, что вы работаете над вами RS, а;))

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

Привет, @ SebastianÐymel. Я получил исключение, когда пытался использовать ваш код. Оказывается, ваша подпись метода не соответствовала ожидаемой сигнатуре метода.Чтобы исправить это, я изменил параметры с '(отправитель объекта, EventArgs e)' на '(отправитель объекта, DependencyPropertyChangedEventArgs dependencyPropertyChangedEventArgs)'. После этого он работал. Большое спасибо за Вашу помощь. – Louie

+0

Привет, @ SebastianÐymel. Я отредактировал ваш ответ немного из-за исключения, которое я получил. – Louie

Смежные вопросы