我发明了一种Metro风格的标签控件,它包含两个级别的标签,就像Zune媒体库一样;一个大,一个小于那个。当您更改第一级的选项卡时,它可以正常工作并动画。两个选项卡中的每一个都包含使用相同模板的另一个TabControl,但是当您更改选项卡时,甚至可以使用标签条动画;像容器TabControl的整个ContentPresenter动画而不是子TabControl的ContentPresenter。如果这是有道理的:P 这是风格:
<Style x:Key="MetroTabControl" TargetType="{x:Type TabControl}">
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Background" Value="White" />
<Setter Property="BorderThickness" Value="0" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<ControlTemplate.Resources>
<Storyboard x:Key="TabSelectionChangedStoryboard">
<DoubleAnimation Storyboard.TargetName="TabControlContent"
Storyboard.TargetProperty="Opacity"
To="100"
From="0"
FillBehavior="HoldEnd"
Duration="0:0:45.0" />
<ThicknessAnimation Storyboard.TargetName="TabControlContent"
Storyboard.TargetProperty="Margin"
From="0,25,0,-25"
To="0,0,0,0"
FillBehavior="HoldEnd"
Duration="0:0:0.3">
</ThicknessAnimation>
</Storyboard>
</ControlTemplate.Resources>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border>
<TabPanel
IsItemsHost="True">
</TabPanel>
</Border>
<Border x:Name="BorderPresenter" BorderThickness="0"
Grid.Row="1"
BorderBrush="White"
Background="White">
<ContentPresenter x:Name="TabControlContent" ContentSource="SelectedContent" Margin="0" >
</ContentPresenter>
</Border>
</Grid>
<ControlTemplate.Triggers>
<EventTrigger RoutedEvent="SelectionChanged">
<BeginStoryboard Storyboard="{StaticResource TabSelectionChangedStoryboard}" />
</EventTrigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
答案 0 :(得分:1)
这是因为SelectionChanged
事件冒泡到父TabControl并触发其动画。作为一种可能的简单解决方案,您可以将SelectionChanged
事件处理程序添加到父TabControl并检查它是否是此事件的原始来源:
<TabControl SelectionChanged="RootTabControl_SelectionChanged">
<TabItem>
<TabControl>
<!-- TabItems here -->
</TabControl>
</TabItem>
</TabControl>
这是代码:
private void RootTabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (sender != e.OriginalSource)
e.Handled = true;
}