WPF自定义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>
编辑:感谢 Vlad,我可以使用渐变边框画笔解决第二个问题。请参阅更新 XAML 以获取解决方案。
编辑:弗拉德解决了第一个问题。
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
对于第二个问题,您也许应该尝试删除剪辑?但请注意可能的问题。
对于第一个问题,您应该尝试在属性
样式触发器 >已选定
。 (编辑:我明白了,您正是这样做的。)看看这是如何在默认模板中实现的 MSDN。请注意,他们也使用ZIndex
。编辑:
我找到了解决您的第一个/最后一个选项卡问题的方法。您需要使用附加属性来指定第一个/最后一个选项卡:
在 TestWindow 类中定义附加属性:
然后,在第一个选项卡中设置此属性:
然后,您应该为其定义一个触发器:
这一定有帮助。
同样的技巧也适用于最后一个选项卡。或者您可以使用数字而不是 bool 作为附加属性。
For the second problem, you should perhaps try to remove the clipping? Beware however of the possible issues.
For the first problem, you should try style trigger on property
IsSelected
. (Edit: I see, you are doing it exactly this way.) Have a look how this is implemented at the default template at MSDN. Note that they are usingZIndex
, too.Edit:
I found a workaround for your first/last tab problem. You need to use attached properties to designate the first/last tab:
In your TestWindow class you define attached property:
Then, in your first tab you set this property:
Then, you should define a trigger for it:
This must help.
The same trick would work with last tab. Or you can have a number instead of bool as attached property.