我有一个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永远不会被调用,大概是因为故事板不再处于活动状态。提示?
答案 0 :(得分: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>
答案 1 :(得分:0)
您可以使用TabControl.SelectionChanged事件。
答案 2 :(得分:0)
您可以为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>