WPF TabItem 和 TabControl 模板组合
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/17671804/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF TabItem and TabControl templates combined
提问by MySqlError
I'm trying to make template for TabControl visual design should be following:
我正在尝试为 TabControl 视觉设计制作模板应该如下:
TabControl content area should have small shadow over TabItems
TabControl 内容区域应该在 TabItems 上有小阴影
but shadow should not be applied to active tab item
但阴影不应应用于活动标签项
problem is that I can only write these templates as separated styles meaning that if I use grid they'll end up in different grids and I can't change Zindex to make only one TabItem pop out over shadow
问题是我只能将这些模板编写为单独的样式,这意味着如果我使用网格,它们最终会出现在不同的网格中,而且我无法更改 Zindex 以仅使一个 TabItem 弹出阴影
I'm using Border to apply shadow
我正在使用 Border 来应用阴影
<Border BorderThickness="0" >
<Border.Effect>
<DropShadowEffect Direction="90" ShadowDepth="1" Color="#b6b6b6" />
</Border.Effect>
</Border>


回答by Adrian Faciu
You could get something similar by changing the background color to a gradient on the TabItem:
您可以通过将 TabItem 上的背景颜色更改为渐变来获得类似的效果:
<Style TargetType="TabItem">
<Style.Triggers>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Background">
<Setter.Value>
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#eeeeee" Offset="0.0"/>
<GradientStop Color="#eeeeee" Offset="0.6"/>
<GradientStop Color="#b6b6b6" Offset="1"/>
</LinearGradientBrush>
</Setter.Value>
</Setter>
</Trigger>
</Style.Triggers>
</Style>
回答by Chris
I came up with this, using the Kaxaml template for a TabControl, it incorporates Adrian's idea of using a LinearGradientBrushto simulate the shadow, I'm using a ControlTemplate:
我想出了这个,使用 TabControl 的 Kaxaml 模板,它结合了 Adrian 使用 aLinearGradientBrush来模拟阴影的想法,我使用的是ControlTemplate:
<TabControl>
<TabControl.Resources>
<LinearGradientBrush x:Key="myBrush" StartPoint="0,0" EndPoint="0,1">
<GradientStop Color="#ffffff" Offset="0.0"/>
<GradientStop Color="#eeeeee" Offset="0.46"/>
<GradientStop Color="#787878" Offset="1"/>
</LinearGradientBrush>
<Style TargetType="{x:Type TabControl}">
<Setter Property="OverridesDefaultStyle" Value="True" />
<Setter Property="SnapsToDevicePixels" Value="True" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<Grid KeyboardNavigation.TabNavigation="Local">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TabPanel Name="HeaderPanel" Grid.Row="0" Panel.ZIndex="1" Margin="0,0,0,-1" IsItemsHost="True"
KeyboardNavigation.TabIndex="1" Background="{StaticResource myBrush}" />
<Border Name="Border" Grid.Row="1" Background="#FFFFFF" BorderBrush="#888888" BorderThickness="1"
KeyboardNavigation.TabNavigation="Local" KeyboardNavigation.DirectionalNavigation="Contained" KeyboardNavigation.TabIndex="2" >
<ContentPresenter Name="PART_SelectedContentHost" Margin="4" ContentSource="SelectedContent" />
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="Foreground" Value="#888888" />
<Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- SimpleStyles: TabItem -->
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border" Margin="0,0,-4,0" Background="#E0E0E0" BorderBrush="#888888" BorderThickness="1,1,1,1" >
<ContentPresenter x:Name="ContentSite" VerticalAlignment="Center" HorizontalAlignment="Center"
ContentSource="Header" Margin="12,2,12,2" RecognizesAccessKey="True"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="False">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter TargetName="Border" Property="BorderThickness" Value="1,1,1,0" />
<Setter TargetName="Border" Property="Background" Value="{StaticResource myBrush}" />
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter TargetName="Border" Property="Background" Value="#EEEEEE" />
<Setter TargetName="Border" Property="BorderBrush" Value="#AAAAAA" />
<Setter Property="Foreground" Value="#888888" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</TabControl.Resources>
<TabItem Header="Test" />
<TabItem Header="Test2" />
<TabItem Header="Test3" />
<TabItem Header="Test4" />
</TabControl>
By way of an explanation.
顺便解释一下。
The LinearGradientBrushmyBrushwill be used in two places, the first is in the TabControl, as the Background:
该LinearGradientBrushmyBrush会在两个地方使用时,首先是在TabControl作为Background:
<TabPanel Name="HeaderPanel" Grid.Row="0" Panel.ZIndex="1" Margin="0,0,0,-1" IsItemsHost="True"
KeyboardNavigation.TabIndex="1" Background="{StaticResource myBrush}" />
The Second is within the TabItemtemplate as the background for all items that aren't selected *using a trigger); you could add additional selected styles if required:
第二个在TabItem模板中作为所有未选择的项目的背景 * 使用触发器);如果需要,您可以添加其他选定的样式:
<Setter TargetName="Border" Property="Background" Value="{StaticResource myBrush}" />
Note: I've changed the background of the TabControlso it's no longer transparent (so it has the shadow. This might fall flat on it's face depending on how you want to use the control (i.e. if you want to show content underneath).
注意:我已经改变了 的背景,TabControl所以它不再透明(所以它有阴影。这可能会落在它的脸上,这取决于你想如何使用控件(即,如果你想在下面显示内容)。
Before this version, I had a different version that used a DropShadowand a clipping grid, which will retain the underlying transparency if you need it. It does rely on you manually matching the gradient brush with the DropShadow. Let me know if you need that other version and I'll post it.
在这个版本之前,我有一个不同的版本,它使用了一个DropShadow和一个剪裁网格,如果你需要它会保留底层的透明度。它确实依赖于您手动将渐变画笔与DropShadow. 如果您需要其他版本,请告诉我,我会发布。
Good luck.
祝你好运。

