TabItem Header 作为标签看起来不同
TabItem Header looks different as a Label
我有一个 TabItem 并且之前在 object 中设置 Header 就像这样,
<TabItem x:Name="Checked_Out_Items" Header="Clients In Use" Height="40" LostFocus="Checked_Out_Items_LostFocus" GotFocus="Checked_Out_Items_GotFocus" BorderThickness="0" >
但是,我 运行 遇到了此选项卡没有 Click 事件的问题。我找到了一个解决方案,我们可以插入一个标签作为此处指定的 header,
how to handle TabItem single click event in WPF?
但是,标签看起来与我需要的完全不同。这是 object 中定义的 Tab Header。
这是带有标签的样子
<TabItem x:Name="Checked_Out_Items" Height="40" LostFocus="Checked_Out_Items_LostFocus" GotFocus="Checked_Out_Items_GotFocus" BorderThickness="0" >
<TabItem.Header>
<Label Content="Clients In Use" Height="40" MouseLeftButtonDown="Checked_Out_Items_Clicked" Width="171" />
</TabItem.Header>
让我们稍微分开一下。
为了处理鼠标单击事件,需要准备一个控件来接收此事件,它需要实现一个处理程序,并且该处理程序必须实际接收该事件。在 TabItem
的情况下,鼠标单击事件由控件消耗,而不将事件释放给用户定义的侦听器。
在 TabItem
级别,最好的选择是处理 PreviewMouseLeftButtonDown
事件,但如果在 child 控件时不应该发生事件处理,则这不是一个选项有自己的处理功能。
所以另一个选择是在 MouseLeftButtonDown
事件到达 TabItem
之前处理它,这意味着在选项卡项的 child 控件中处理它。
如前所述,为了接收事件,控件需要准备好接收事件。这意味着,它需要 Background
而不是 null
(可以是 Transparent
)和 IsHitTestEnabled="True"
(在大多数情况下是默认值)并且它必须实际处理事件。
对于展示,我使用 Red
而不是 Transparent
背景色。红色区域是捕获和处理鼠标点击的地方。
<TabItem Padding="0">
<TabItem.Header>
<Border Height="30" Width="50"
Background="Red" MouseLeftButtonDown="Item_MouseLeftButtonDown">
<ContentPresenter
VerticalAlignment="Center" HorizontalAlignment="Center"
Content="T2"/>
</Border>
</TabItem.Header>
Test Content 2
</TabItem>
或者,为了更好地分离 header 内容和点击处理,可以使用 HeaderTemplate
:
<TabItem Header="T3" Padding="0">
<TabItem.HeaderTemplate>
<DataTemplate>
<Border MinHeight="30" MinWidth="50"
Background="Red" MouseLeftButtonDown="Item_MouseLeftButtonDown">
<ContentPresenter
VerticalAlignment="Center" HorizontalAlignment="Center"
Content="{Binding}"/>
</Border>
</DataTemplate>
</TabItem.HeaderTemplate>
Test Content 3
</TabItem>
任何依赖 child 控件的方法的问题是,TabItem
仍然有一个边框,如果用户单击该边框,则单击将在 child 控件和选项卡将在不执行单击处理程序的情况下被选中。
因此,处理选项卡更改(不是点击!)的另一种方法是处理 TabControl.SelectionChanged
事件并过滤实际上源自 TabControl
而不是某些内部内容元素的事件.
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source == sender)
{
// this selection change is actually issued because of a tab change
}
}
我刚刚意识到的另一件事:可以在 TabItem.PreviewMouseLeftButtonDown
中使用相同的条件来过滤对 tabitem header 的点击与来自内容区域的点击事件。
编辑:
Label
看起来不同的原因是,TabItem
的字体样式处于活动状态,而 Label
正在使用其某些内部样式,忽略了 TabItem
风格。
我有一个 TabItem 并且之前在 object 中设置 Header 就像这样,
<TabItem x:Name="Checked_Out_Items" Header="Clients In Use" Height="40" LostFocus="Checked_Out_Items_LostFocus" GotFocus="Checked_Out_Items_GotFocus" BorderThickness="0" >
但是,我 运行 遇到了此选项卡没有 Click 事件的问题。我找到了一个解决方案,我们可以插入一个标签作为此处指定的 header, how to handle TabItem single click event in WPF?
但是,标签看起来与我需要的完全不同。这是 object 中定义的 Tab Header。
这是带有标签的样子
<TabItem x:Name="Checked_Out_Items" Height="40" LostFocus="Checked_Out_Items_LostFocus" GotFocus="Checked_Out_Items_GotFocus" BorderThickness="0" >
<TabItem.Header>
<Label Content="Clients In Use" Height="40" MouseLeftButtonDown="Checked_Out_Items_Clicked" Width="171" />
</TabItem.Header>
让我们稍微分开一下。
为了处理鼠标单击事件,需要准备一个控件来接收此事件,它需要实现一个处理程序,并且该处理程序必须实际接收该事件。在 TabItem
的情况下,鼠标单击事件由控件消耗,而不将事件释放给用户定义的侦听器。
在 TabItem
级别,最好的选择是处理 PreviewMouseLeftButtonDown
事件,但如果在 child 控件时不应该发生事件处理,则这不是一个选项有自己的处理功能。
所以另一个选择是在 MouseLeftButtonDown
事件到达 TabItem
之前处理它,这意味着在选项卡项的 child 控件中处理它。
如前所述,为了接收事件,控件需要准备好接收事件。这意味着,它需要 Background
而不是 null
(可以是 Transparent
)和 IsHitTestEnabled="True"
(在大多数情况下是默认值)并且它必须实际处理事件。
对于展示,我使用 Red
而不是 Transparent
背景色。红色区域是捕获和处理鼠标点击的地方。
<TabItem Padding="0">
<TabItem.Header>
<Border Height="30" Width="50"
Background="Red" MouseLeftButtonDown="Item_MouseLeftButtonDown">
<ContentPresenter
VerticalAlignment="Center" HorizontalAlignment="Center"
Content="T2"/>
</Border>
</TabItem.Header>
Test Content 2
</TabItem>
或者,为了更好地分离 header 内容和点击处理,可以使用 HeaderTemplate
:
<TabItem Header="T3" Padding="0">
<TabItem.HeaderTemplate>
<DataTemplate>
<Border MinHeight="30" MinWidth="50"
Background="Red" MouseLeftButtonDown="Item_MouseLeftButtonDown">
<ContentPresenter
VerticalAlignment="Center" HorizontalAlignment="Center"
Content="{Binding}"/>
</Border>
</DataTemplate>
</TabItem.HeaderTemplate>
Test Content 3
</TabItem>
任何依赖 child 控件的方法的问题是,TabItem
仍然有一个边框,如果用户单击该边框,则单击将在 child 控件和选项卡将在不执行单击处理程序的情况下被选中。
因此,处理选项卡更改(不是点击!)的另一种方法是处理 TabControl.SelectionChanged
事件并过滤实际上源自 TabControl
而不是某些内部内容元素的事件.
private void TabControl_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.Source == sender)
{
// this selection change is actually issued because of a tab change
}
}
我刚刚意识到的另一件事:可以在 TabItem.PreviewMouseLeftButtonDown
中使用相同的条件来过滤对 tabitem header 的点击与来自内容区域的点击事件。
编辑:
Label
看起来不同的原因是,TabItem
的字体样式处于活动状态,而 Label
正在使用其某些内部样式,忽略了 TabItem
风格。