wpf contextmenu 点击打开子菜单
wpf contextmenu open submenu on click
我在 WPF 中有一个包含多个子菜单的上下文菜单。默认行为是,如果您将鼠标悬停在其下方有项目的菜单项上,它将打开子菜单。但是,我想更改它,使其不会在悬停时打开,而是在左键单击时打开。
我复制了 MenuItem 的默认模板。在此,我做了一些修改:
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
<!-- some default template code -->
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="Transparent"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource MenuItem.Highlight.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{StaticResource Menu.Disabled.Foreground}"/>
<Setter Property="Fill" TargetName="Glyph" Value="{StaticResource Menu.Disabled.Foreground}"/>
<Setter Property="Fill" TargetName="RightArrow" Value="{StaticResource Menu.Disabled.Foreground}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="SubMenuScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
<!-- my code to supress the opening of the submenu in mouseover -->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsOpen" TargetName="PART_Popup" Value="False"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
起初这似乎奏效了。但是,当我将鼠标慢慢移动到另一个 menuItem 时,它会出现片刻 - 可能 space 'IsMouseOver' 不正确,但子菜单仍然显示。
我怎样才能完全禁止它 - 除非有人点击 menuItem?
此行为是由 TemplateBinding IsSubmenuOpen
引起的,它会在触发器将其设置回 False 之前自动将 IsOpen
设置为 True。
<Popup
Name="PART_Popup"
Placement="Right"
HorizontalOffset="-4"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
...
</Border>
</Popup>
由于您已经使用点击事件连接了东西,您只需设置
IsOpen="False"
另一种解决方法是设置
IsOpen="{TemplateBinding IsChecked}"
并在每次单击 MenuItem 时设置 IsChecked 属性。
我在 WPF 中有一个包含多个子菜单的上下文菜单。默认行为是,如果您将鼠标悬停在其下方有项目的菜单项上,它将打开子菜单。但是,我想更改它,使其不会在悬停时打开,而是在左键单击时打开。
我复制了 MenuItem 的默认模板。在此,我做了一些修改:
<ControlTemplate x:Key="{ComponentResourceKey ResourceId=SubmenuHeaderTemplateKey, TypeInTargetAssembly={x:Type MenuItem}}" TargetType="{x:Type MenuItem}">
<!-- some default template code -->
<ControlTemplate.Triggers>
<Trigger Property="IsSuspendingPopupAnimation" Value="true">
<Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
</Trigger>
<Trigger Property="Icon" Value="{x:Null}">
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsChecked" Value="True">
<Setter Property="Visibility" TargetName="GlyphPanel" Value="Visible"/>
<Setter Property="Visibility" TargetName="Icon" Value="Collapsed"/>
</Trigger>
<Trigger Property="IsHighlighted" Value="True">
<Setter Property="Background" TargetName="templateRoot" Value="Transparent"/>
<Setter Property="BorderBrush" TargetName="templateRoot" Value="{StaticResource MenuItem.Highlight.Border}"/>
</Trigger>
<Trigger Property="IsEnabled" Value="False">
<Setter Property="TextElement.Foreground" TargetName="templateRoot" Value="{StaticResource Menu.Disabled.Foreground}"/>
<Setter Property="Fill" TargetName="Glyph" Value="{StaticResource Menu.Disabled.Foreground}"/>
<Setter Property="Fill" TargetName="RightArrow" Value="{StaticResource Menu.Disabled.Foreground}"/>
</Trigger>
<Trigger Property="ScrollViewer.CanContentScroll" SourceName="SubMenuScrollViewer" Value="false">
<Setter Property="Canvas.Top" TargetName="OpaqueRect" Value="{Binding VerticalOffset, ElementName=SubMenuScrollViewer}"/>
<Setter Property="Canvas.Left" TargetName="OpaqueRect" Value="{Binding HorizontalOffset, ElementName=SubMenuScrollViewer}"/>
</Trigger>
<!-- my code to supress the opening of the submenu in mouseover -->
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="IsOpen" TargetName="PART_Popup" Value="False"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
起初这似乎奏效了。但是,当我将鼠标慢慢移动到另一个 menuItem 时,它会出现片刻 - 可能 space 'IsMouseOver' 不正确,但子菜单仍然显示。
我怎样才能完全禁止它 - 除非有人点击 menuItem?
此行为是由 TemplateBinding IsSubmenuOpen
引起的,它会在触发器将其设置回 False 之前自动将 IsOpen
设置为 True。
<Popup
Name="PART_Popup"
Placement="Right"
HorizontalOffset="-4"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border
...
</Border>
</Popup>
由于您已经使用点击事件连接了东西,您只需设置
IsOpen="False"
另一种解决方法是设置
IsOpen="{TemplateBinding IsChecked}"
并在每次单击 MenuItem 时设置 IsChecked 属性。