【问题标题】:Animation during SelectionChangedSelectionChanged 期间的动画
【发布时间】:2012-08-17 18:30:42
【问题描述】:

我有一个TabControl,其中每个TabItem 都有一个单独的控件作为其Content 元素。现在,我可以使用UserControl.Loaded EventTrigger 在切换到选项卡时轻松执行情节提要。但是,我还想在从一个选项卡切换到另一个选项卡时运行退出动画(即允许旧的 Content 控件以动画方式离开,然后是新的 Content 控件的入口动画)。

是否可以使用标准 WPF 结构来做到这一点?

如果没有,我将如何开发一个自定义解决方案来处理这个问题?

编辑: 我继续做了一个修改后的 TabControl,它扩展了基本的 TabControl 并覆盖了它的 OnSelectionChanged 方法,如下所示:

protected override void OnSelectionChanged(SelectionChangedEventArgs e)
{
    if (e.AddedItems.Count == 1 && e.RemovedItems.Count == 1)
    {
        var oldTab = e.RemovedItems[0] as TabItem;

        if (oldTab != null)
        {
            var exitStoryboard = /** code to find the storyboard **/
            if (exitStoryboard != null)
            {
                exitStoryboard.Completed = (_, __) => base.OnSelectionChanged(e);
                exitStoryboard.Begin();
                return;
            }
        }
    }
    base.OnSelectionChanged(e);
}

这可行,除非我在选项卡之间单击得太快,在这种情况下 base.OnSelectionChanged 永远不会被调用,大概是因为情节提要不再处于活动状态。提示?

【问题讨论】:

    标签: wpf storyboard tabcontrol selectionchanged


    【解决方案1】:

    这里有2个选项卡的解决方案,大体思路是在选择改变后弹出最后一个选项卡的图像,然后淡入当前选项卡。

    通过跟踪属性中 VisualBrush 的最后一个选项卡而不是此处使用的硬编码“其他”选项卡,您可以通过一点点努力将其通用化为任意数量的选项卡。

    <Grid xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
       <TabControl>
          <TabItem x:Name="tab1" Header="Tab 1">
             <Border Background="Transparent">
                <Grid>
                   <TextBlock FontSize="40" Foreground="Red" Text="Tab 1 Contents">
                      <TextBlock.Triggers>
                         <EventTrigger RoutedEvent="Loaded">
                            <BeginStoryboard>
                               <Storyboard>
                                  <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
                                     <DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="0.0"/>
                                  </DoubleAnimationUsingKeyFrames>
                                  <DoubleAnimation
                                     Duration="0:0:0.25"
                                     From="1"
                                     Storyboard.TargetName="tab2Shadow"
                                     Storyboard.TargetProperty="Opacity"
                                     To="0"/>
                                  <DoubleAnimation
                                     BeginTime="0:0:0.25"
                                     Duration="0:0:0.25"
                                     From="0"
                                     Storyboard.TargetProperty="Opacity"
                                     To="1"/>
                               </Storyboard>
                            </BeginStoryboard>
                         </EventTrigger>
                      </TextBlock.Triggers>
                   </TextBlock>
                   <Rectangle x:Name="tab2Shadow">
                      <Rectangle.Fill>
                         <VisualBrush
                            AlignmentX="Left"
                            AlignmentY="Top"
                            AutoLayoutContent="False"
                            Stretch="None"
                            Visual="{Binding ElementName=tab2, Path=Content}"/>
                      </Rectangle.Fill>
                   </Rectangle>
                </Grid>
             </Border>
          </TabItem>
          <TabItem x:Name="tab2" Header="Tab 2">
             <Border Background="Transparent">
                <Grid>
                   <TextBlock FontSize="40" Foreground="Red" Text="Tab 2 Contents">
                      <TextBlock.Triggers>
                         <EventTrigger RoutedEvent="Loaded">
                            <BeginStoryboard>
                               <Storyboard>
                                  <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="Opacity">
                                     <DiscreteDoubleKeyFrame KeyTime="0:0:0" Value="0.0"/>
                                  </DoubleAnimationUsingKeyFrames>
                                  <DoubleAnimation
                                     Duration="0:0:0.25"
                                     From="1"
                                     Storyboard.TargetName="tab1Shadow"
                                     Storyboard.TargetProperty="Opacity"
                                     To="0"/>
                                  <DoubleAnimation
                                     BeginTime="0:0:0.25"
                                     Duration="0:0:0.25"
                                     From="0"
                                     Storyboard.TargetProperty="Opacity"
                                     To="1"/>
                               </Storyboard>
                            </BeginStoryboard>
                         </EventTrigger>
                      </TextBlock.Triggers>
                   </TextBlock>
                   <Rectangle x:Name="tab1Shadow">
                      <Rectangle.Fill>
                         <VisualBrush
                            AlignmentX="Left"
                            AlignmentY="Top"
                            AutoLayoutContent="False"
                            Stretch="None"
                            Visual="{Binding ElementName=tab1, Path=Content}"/>
                      </Rectangle.Fill>
                   </Rectangle>
                </Grid>
             </Border>
          </TabItem>
       </TabControl>
    </Grid>
    

    【讨论】:

    • 这看起来很有希望,尽管我想我只能做一个对 XAML 元素一无所知的基本动画,除非我想在单独的视觉画笔中跟踪它们?
    • 如果动画在选择离开时在旧选项卡上播放,VisualBrush 将在旧选项卡上显示动画控件,因此您可以对它们进行一些操作,而不是上面的简单淡入淡出效果。跨度>
    【解决方案2】:

    您可以使用 TabControl.SelectionChanged 事件。

    【讨论】:

    • 我已经尝试过了。在动画可以运行之前,选项卡选择会发生变化。
    【解决方案3】:

    您可以为您的 tabcontrol 定义自定义样式并在 Selector.SelectionChanged RoutedEvent 上做动画

            <Style x:Key="{x:Type TabControl}"
               TargetType="TabControl">
            <Setter Property="VerticalContentAlignment" Value="Stretch" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="TabControl">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="40" />
                                <RowDefinition />
                            </Grid.RowDefinitions>
    
                            <UniformGrid Grid.Row="0"
                                         Rows="1"
                                         IsItemsHost="True" />
                            <ContentPresenter x:Name="TabContent"
                                              Grid.Row="2"
                                              Content="{TemplateBinding SelectedContent}">
    
                            </ContentPresenter>
                        </Grid>
    
                        <ControlTemplate.Triggers>
                            <EventTrigger RoutedEvent="Selector.SelectionChanged">
                                <BeginStoryboard>
                                    <Storyboard>
                                        <DoubleAnimation From="0"
                                                         To="1"
                                                         Storyboard.TargetProperty="Opacity"
                                                         Storyboard.TargetName="TabContent"
                                                         Duration="0:0:0.5" />
                                    </Storyboard>
                                </BeginStoryboard>
                            </EventTrigger>
                        </ControlTemplate.Triggers>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-01-18
      • 1970-01-01
      • 2010-10-23
      • 2020-08-09
      • 2020-08-30
      相关资源
      最近更新 更多