如何让tabitem的header只响应鼠标事件

发布于 09-08 11:00 字数 776 浏览 13 评论 0原文

我试图仅让 TabItem 的标题发送事件。

到目前为止,我有我的 xaml...

<TabControl>
    <TabItem Header="tab 1">
             Any text
    </TabItem>
    <TabItem Header="tab 2">
        <TextBox>blah</TextBox>
    </TabItem>
    <TabControl.Resources>
        <Style TargetType="TabItem">
            <EventSetter Event="MouseDoubleClick" Handler="TabItemMouseDoubleClick"/>
        </Style>
    </TabControl.Resources>
</TabControl>

...和我的事件处理程序...

void TabItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
{}

现在,当双击选项卡项标题时,事件会触发,当单击选项卡项内容区域时,它不会触发(这就是我想要的) ),但是当我在 TabItem 中放置一个文本框时,双击该文本框就会触发该事件。我试图仅获取 TabItem 的标题来触发事件 - 有什么想法吗?

I'm trying to make only the header of the TabItem send an event.

So far I have my xaml...

<TabControl>
    <TabItem Header="tab 1">
             Any text
    </TabItem>
    <TabItem Header="tab 2">
        <TextBox>blah</TextBox>
    </TabItem>
    <TabControl.Resources>
        <Style TargetType="TabItem">
            <EventSetter Event="MouseDoubleClick" Handler="TabItemMouseDoubleClick"/>
        </Style>
    </TabControl.Resources>
</TabControl>

...and my event handler...

void TabItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
{}

Now, when double clicking the tab item header the event fires, when clicking the tab item content area it doesn't fire (which is what I want), but when I put a text box in the TabItem, the event fires upon double clicking the textbox. I'm trying to get only the header of the TabItem to fire the event - any ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

才能让你更想念2024-09-15 11:00:35

您所看到的是 WPF 冒泡事件模型的效果,在该模型中,子级中发生的事件通常会冒泡到父级。

您可能需要做的是检查 ,或者可能是原始来源 MouseButtonEventArgs 的属性,并且仅响应来自 TabItem 类型的事件。

另一件要尝试的事情是检查 IsMouseDirectlyOver如果鼠标位于父元素的边界内,但实际上位于子元素上方,则该属性应返回 false。

您可以尝试设置 IsHitTestVisible ,例如,选项卡项中的文本框,但您可能会发现它具有不良副作用,例如单击文本时不会更改所选选项卡。

What you're seeing is the effect of WPF's bubbling event model whereby events that happen in the children usually bubble up to the parent.

What you'll probably need to do is check the Source, or possibly the OriginalSource properties of the MouseButtonEventArgs, and only respond to events that are coming from TabItem types.

Another thing to try is checking the IsMouseDirectlyOver property which should return false if the mouse is inside the bounds of the parent, but is actually over a child element.

You might try setting IsHitTestVisible on, say, the TextBox in the tab item, but you would probably find that has undesirable side-effects, like not changing the selected tab when you click on the text.

兔姬2024-09-15 11:00:35

您可以通过使用 HeaderTemplate 来获得您想要的行为,如下所示(这是非常基本的,因此您需要对其进行修复以整理标签的高度...等)。只需用此设置器替换当前的事件设置器:

<Setter Property="HeaderTemplate">
    <Setter.Value>
        <DataTemplate>
            <Label Content={Binding}>
                <Label.Style>
                    <Style TargetType="Label">
                        <EventSetter Event="MouseDoubleClick" Handler="TabItemMouseDoubleClick"/>
                    </Style>
                </Label.Style>
            </Label>
        </DataTemplate>
    </Setter.Value>
</Setter>

You can get the behaviour you want by using a HeaderTemplate as follows (this is very basic so you will need to fix it up to sort out the heights of the label...etc). Just replace your current eventsetter with this setter:

<Setter Property="HeaderTemplate">
    <Setter.Value>
        <DataTemplate>
            <Label Content={Binding}>
                <Label.Style>
                    <Style TargetType="Label">
                        <EventSetter Event="MouseDoubleClick" Handler="TabItemMouseDoubleClick"/>
                    </Style>
                </Label.Style>
            </Label>
        </DataTemplate>
    </Setter.Value>
</Setter>
假扮的天使2024-09-15 11:00:35

TabItem 鼠标双击事件:

private void TabOnMouseDoubleClick(object sender, MouseButtonEventArgs mouseButtonEventArgs)
        {
            var tabItem = (sender as TabItem);
            var mo = (tabItem.Content as UIElement).IsMouseOver;
            if (!mo)
                {
                    //Here you know you are working with header
                }
        }

TabItem MouseDoubleClick event:

private void TabOnMouseDoubleClick(object sender, MouseButtonEventArgs mouseButtonEventArgs)
        {
            var tabItem = (sender as TabItem);
            var mo = (tabItem.Content as UIElement).IsMouseOver;
            if (!mo)
                {
                    //Here you know you are working with header
                }
        }
泪痕残2024-09-15 11:00:35

我与最初的问题有相同的需求,但出于某种原因,我不想深入研究 XAML 来使其正常工作......所以这个快速的仅代码解决方案对我来说效果很好:

void TabItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    Point point = e.GetPosition(tabItem);
    if (point.Y > 32)
    {
        // Click was below the tab header
        // Note: 32 refers to the height of the tab header in pixels.
        return;
    }

    // handle the double-click on the header here ...
    // ...
}

I have the same need as the original question, but for one reason and another I don't want to delve into XAML to get this working ... so this quick'n'dirty code-only solution worked well for me:

void TabItemMouseDoubleClick(object sender, MouseButtonEventArgs e)
{
    Point point = e.GetPosition(tabItem);
    if (point.Y > 32)
    {
        // Click was below the tab header
        // Note: 32 refers to the height of the tab header in pixels.
        return;
    }

    // handle the double-click on the header here ...
    // ...
}
一曲琵琶半遮面シ2024-09-15 11:00:35

对于其他人来说,获取仅发送事件的 tabItems 标头的最终 xaml 是...

    <TabControl>
        <TabItem Header="tab 1">
                 Any text
        </TabItem>
        <TabItem Header="tab 2">
            <TextBox>blah</TextBox>
        </TabItem>
        <TabControl.Resources>
            <Style TargetType="TabItem">

                <Setter Property="HeaderTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Label Content="{Binding}">
                                <Label.Style>
                                    <Style TargetType="Label">
                                        <EventSetter Event="MouseDoubleClick" Handler="TabItemMouseDoubleClick"/>
                                    </Style>
                                </Label.Style>
                            </Label>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TabControl.Resources>
    </TabControl>

For others, the final xaml to get the tabItems header only sending the event is...

    <TabControl>
        <TabItem Header="tab 1">
                 Any text
        </TabItem>
        <TabItem Header="tab 2">
            <TextBox>blah</TextBox>
        </TabItem>
        <TabControl.Resources>
            <Style TargetType="TabItem">

                <Setter Property="HeaderTemplate">
                    <Setter.Value>
                        <DataTemplate>
                            <Label Content="{Binding}">
                                <Label.Style>
                                    <Style TargetType="Label">
                                        <EventSetter Event="MouseDoubleClick" Handler="TabItemMouseDoubleClick"/>
                                    </Style>
                                </Label.Style>
                            </Label>
                        </DataTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
        </TabControl.Resources>
    </TabControl>
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文