如何让ContextMenu中MenuItem仅在鼠标悬停自身时显示Tooltip?
这个问题我之前也踩过坑——WPF的ToolTipService属性默认会向下继承,所以你给父MenuItem设置的InitialShowDelay会被子项继承,导致子项也能触发Tooltip。这里有两个不用挨个给子项加属性的简单解决办法:
方法1:把Tooltip绑定到父MenuItem的Header元素上
既然我们只希望父MenuItem的文字部分触发Tooltip,那直接把Tooltip加到Header的TextBlock里就行,这样Tooltip就不会被子项继承了:
<Button Content="Push"> <Button.ContextMenu> <ContextMenu> <MenuItem ToolTipService.InitialShowDelay="5000"> <MenuItem.Header> <!-- 把Tooltip绑定到TextBlock上,仅当鼠标悬停在文字上时显示 --> <TextBlock Text="Want ToolTip Here" ToolTip="ToolTip"/> </MenuItem.Header> <MenuItem Header="Do Not Want ToolTip Here"/> <MenuItem Header="Or Here"/> <MenuItem Header="Or Here"/> </MenuItem> </ContextMenu> </Button.ContextMenu> </Button>
原理很简单:Tooltip现在属于Header里的TextBlock,而不是MenuItem本身。当你把鼠标移到子项上时,子项没有自己的Tooltip,也不会继承父项的(因为父项的Tooltip不在MenuItem节点上),自然就不会触发了。
方法2:用全局样式禁用子项的ToolTipService
如果你的ContextMenu里有多个顶级MenuItem,不想挨个改Header,可以用样式统一处理——给所有子MenuItem禁用ToolTipService,只保留顶级项的功能:
<Button Content="Push"> <Button.ContextMenu> <ContextMenu> <ContextMenu.Resources> <Style TargetType="MenuItem"> <!-- 默认禁用所有MenuItem的Tooltip功能 --> <Setter Property="ToolTipService.IsEnabled" Value="False"/> <Style.Triggers> <!-- 只有没有父MenuItem的顶级项,才启用Tooltip --> <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=MenuItem}}" Value="{x:Null}"> <Setter Property="ToolTipService.IsEnabled" Value="True"/> </DataTrigger> </Style.Triggers> </Style> </ContextMenu.Resources> <MenuItem ToolTip="ToolTip" Header="Want ToolTip Here" ToolTipService.InitialShowDelay="5000"> <MenuItem Header="Do Not Want ToolTip Here"/> <MenuItem Header="Or Here"/> <MenuItem Header="Or Here"/> </MenuItem> </ContextMenu> </Button.ContextMenu> </Button>
这个样式会自动应用到ContextMenu里的所有MenuItem:通过RelativeSource判断当前项是否有父MenuItem,没有的就是顶级项,启用Tooltip;有父项的就是子菜单,禁用Tooltip。
内容的提问来源于stack exchange,提问作者M Kloster
相关产品推荐
相关产品推荐

