xsl*_*xsl 12 wpf customization xaml tabcontrol
我必须开发一个自定义的选项卡控件,并决定用WPF/XAML创建它,因为无论如何我打算学习它.它完成时应该看起来像这样:

到目前为止我取得了很好的进展,但还有两个问题:
只有第一个/最后一个标签项应该有一个圆角的左上角/左下角.是否可以修改这些项目的样式,类似于我对所选标签项的方式?
选定的选项卡项右侧不应有边框.我试图用z-index和重叠来完成这个,但结果相当令人失望.有没有其他方法可以做到这一点?

XAML:
<Window x:Class="MyProject.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="TestWindow" Height="350" Width="500" Margin="5" Background="LightGray">
<Window.Resources>
<LinearGradientBrush x:Key="SelectedBorderBrush" StartPoint="0,0" EndPoint="1,0">
<GradientBrush.GradientStops>
<GradientStopCollection>
<GradientStop Color="Gray" Offset="0.965"/>
<GradientStop Color="WhiteSmoke" Offset="1.0"/>
</GradientStopCollection>
</GradientBrush.GradientStops>
</LinearGradientBrush>
<Style TargetType="{x:Type TabControl}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabControl}">
<DockPanel>
<Border
Panel.ZIndex="50"
Margin="0,100,-1,0"
Background="#FFAAAAAA"
BorderBrush="Gray"
CornerRadius="7,0,0,7"
BorderThickness="1">
<TabPanel
Margin="0,0,0,0"
IsItemsHost="True" />
</Border>
<Border
Background="WhiteSmoke"
BorderBrush="Gray"
BorderThickness="1"
CornerRadius="7,7,7,0" >
<ContentPresenter
ContentSource="SelectedContent" />
</Border>
</DockPanel>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type TabItem}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type TabItem}">
<Grid>
<Border Name="Border"
Background="#FFAAAAAA"
CornerRadius="7,0,0,0"
BorderBrush="Gray"
BorderThickness="0,0,0,1"
Panel.ZIndex="50"
Margin="0,0,0,0"
>
<ContentPresenter x:Name="ContentSite"
VerticalAlignment="Center"
HorizontalAlignment="Left"
ContentSource="Header"
Margin="10,10,10,10"/>
</Border>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="Panel.ZIndex" Value="100" />
<Setter Property="Margin" Value="0,0,-2,0" />
<Setter TargetName="Border"
Property="BorderBrush"
Value="{StaticResource SelectedBorderBrush}"/>
<Setter TargetName="Border"
Property="Background"
Value="WhiteSmoke" />
<Setter TargetName="Border"
Property="CornerRadius"
Value="0,0,0,0" />
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Window.Resources>
<Grid>
<TabControl Name="_menuTabControl" TabStripPlacement="Left" Margin="5">
<TabItem Name="_tabItem1" Header="First Tab Item" ></TabItem>
<TabItem Name="_tabItem2" Header="Second Tab Item" >
<Grid />
</TabItem>
<TabItem Name="_tabItem3" Header="Third Tab Item" >
<Grid />
</TabItem>
</TabControl>
</Grid>
Run Code Online (Sandbox Code Playgroud)
编辑:感谢Vlad,我可以使用渐变边框画笔修复第二个问题.请参阅XAML的更新以获取解决方案.
编辑:弗拉德修复了第一个问题.
对于第二个问题,您应该尝试删除剪辑?但请注意可能存在的问题.
对于第一个问题,您应该尝试在属性上触发样式IsSelected.(编辑:我明白了,你正是这样做的.)看看这是如何在MSDN的默认模板上实现的.请注意,他们也在使用ZIndex.
编辑:
我找到了第一个/最后一个标签问题的解决方法.您需要使用附加属性来指定第一个/最后一个选项卡:
在TestWindow类中,您可以定义附加属性:
public static bool GetIsFirstTab(DependencyObject obj)
{
return (bool)obj.GetValue(IsFirstTabProperty);
}
public static void SetIsFirstTab(DependencyObject obj, bool value)
{
obj.SetValue(IsFirstTabProperty, value);
}
public static readonly DependencyProperty IsFirstTabProperty =
DependencyProperty.RegisterAttached("IsFirstTab", typeof(bool),
typeof(TestWindow), new UIPropertyMetadata(false));
Run Code Online (Sandbox Code Playgroud)
然后,在第一个选项卡中设置此属性:
<Window x:Class="MyProject.TestWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:MyProject"
...
/>
...
<TabItem Name="_tabItem1" Header="First Tab Item"
local:TestWindow.IsFirstTab="true">
</TabItem>
Run Code Online (Sandbox Code Playgroud)
然后,您应该为它定义一个触发器:
<Trigger Property="IsSelected" Value="True">
<Setter TargetName="Border"
Property="Background"
Value="WhiteSmoke" />
</Trigger>
<Trigger Property="local:Window1.IsFirstTab" Value="True">
<Setter TargetName="Border"
Property="Background"
Value="Red" />
</Trigger>
Run Code Online (Sandbox Code Playgroud)
这必须有所帮助.
同样的技巧适用于最后一个标签.或者您可以使用数字而不是bool作为附加属性.