WPF - 如何在鼠标离开时隐藏菜单?

时间:2014-03-19 14:11:35

标签: wpf hide menuitem mouseleave

我对WPF非常陌生,现在我一直在苦苦思索如何在鼠标离开子菜单时隐藏MenuItem的子菜单。

我尝试直接在父MenuItem上应用触发器,但这仅适用于其标头。我试图操纵MenuItem.ItemsPanel我没有取得任何成功。

我已经设法将子项包装在Menu控件中(在父MenuItem中)并在其上应用触发器,但是有不必要的副作用(比如所有菜单都突出显示而不是一个项目)。

任何帮助将不胜感激,

伊詹

<Menu .... >
    <MenuItem .... > // parent MenuItem
        <MenuItem .... />
        <MenuItem .... />
        <MenuItem .... />
        <MenuItem .... />
    </MenuItem>
</Menu>

1 个答案:

答案 0 :(得分:0)

我是 XAML 的新手,这可能并不完美,但它对我有用 - 我需要相同的功能,并在经过数小时的搜索和尝试后想出了这个,这就是我想发布它的原因,因为我不能在任何地方找到答案。有用于样式和对齐的额外代码,但您可以忽略它:

仅 - Xaml 用于在鼠标离开时关闭菜单:

 <!--.........Override PopUp so it can close on Mouse Leave + Style ----------------------------------->            
                    <!--#3-Top Menu - MenuItem-->
                    <Style x:Key="menu_TopMenu_MenuItem_Style" TargetType="{x:Type MenuItem}">
                        <Setter Property="Template">
                            <Setter.Value>
                            
                            
                            <ControlTemplate x:Name="menuItem" TargetType="{x:Type MenuItem}">
                                <Border x:Name="templateRoot"  BorderThickness="1" CornerRadius="1"  SnapsToDevicePixels="True">
                                    <Grid VerticalAlignment="Center">
                                        <Grid.ColumnDefinitions>
                                            <ColumnDefinition Width="Auto"/>
                                            <ColumnDefinition Width="Auto"/>
                                        </Grid.ColumnDefinitions>
                                        
                                        <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                       
                                        <Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False"  IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="None" Placement="Bottom">
                                            <Border x:Name="SubMenuBorder">
                                                <ScrollViewer x:Name="SubMenuScrollViewer" 
                                              Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}"
                                              Background="Blue" Margin="0" Padding="0">
                                                    <Grid  RenderOptions.ClearTypeHint="Enabled">   
                                                        <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                                                            <Rectangle x:Name="OpaqueRect" Stroke="#8a919c"  RadiusX="5" RadiusY="5" StrokeThickness="1" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}">
                                                                <Rectangle.Fill>
                                                                <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                                                                        <GradientStop Color="#FF404957" Offset="0.144"/>
                                                                        <GradientStop Color="#FF2B3F47" Offset="0.994"/>
                                                                    </LinearGradientBrush>
                                                                </Rectangle.Fill>    
                                                            </Rectangle>
                                                        </Canvas>
                                                        <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle" />
                                                    </Grid>
                                                </ScrollViewer>
                                            </Border>    
                                        </Popup>
                                        
                                    </Grid>
                                </Border>
            
                                
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSuspendingPopupAnimation" Value="True">
                                        <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
                                    </Trigger>
                                
                                    
                                    <Trigger Property="IsKeyboardFocusWithin" Value="True">
                                        <Setter TargetName="templateRoot" Property="Background" Value="#FF576DB9" />
                                    </Trigger>
            
            
                                    <Trigger Property="IsMouseOver" Value="True">
                                        <Setter Property="Background" TargetName="templateRoot" Value="#7F26DACA"/>
                                        <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26DAB9"/>
            
                                        
                                        <Setter Property="IsOpen" TargetName="PART_Popup" Value="true"/>
                                        <Setter Property="Cursor" Value="Hand"/>
                                        <Setter Property="Focusable" Value="False"/>
                                    </Trigger>
            
                                  
                                       
                                    
            
                                    <!--On - MouseLeave - Close PopUp - "Menu" -->
                                    <MultiTrigger>
                                        <MultiTrigger.Conditions>
                                            <Condition Property="IsKeyboardFocusWithin" Value="false" />
                                            <Condition Property="IsMouseOver" Value="false" />
                                        </MultiTrigger.Conditions>
            
                                        <MultiTrigger.Setters>
                                            <Setter Property="IsOpen" TargetName="PART_Popup" Value="false"/>
                                        </MultiTrigger.Setters>
                                    </MultiTrigger>
            
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                            
                        </Setter.Value>  
                    </Setter>

================================================ ========================== 详细:

#1 - MainWindow.xaml - 文件 - “下面的菜单代码”:

<Window x:Class="PaintApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:PaintApp"
        mc:Ignorable="d"   
        Title="MainWindow" Height="450" Width="800">


    <!--GRID-->
    <Grid x:Name="grid_MainGrid">
<!--..............................The Menu Code....................................................-->  

        <!--Top Menu-->
        <DockPanel x:Name="dockPanel_Menu_TopMenu" Style="{DynamicResource dockPanel_Menu_TopMenu_Style}">
            <Menu x:Name="menu_TopMenu" Style="{DynamicResource menu_TopMenu_Style}">

                <MenuItem Header="File" Style="{DynamicResource menu_TopMenu_MenuItem_Style}">
                    <MenuItem Header="New"/>
                    <Separator Style="{DynamicResource menu_TopMenu_Seperator_Style}"/>
                    <MenuItem Header="Open"/>
                    <Separator Style="{DynamicResource menu_TopMenu_Seperator_Style}"/>
                    <MenuItem  Header="Save"/>

                </MenuItem>
                <MenuItem Header="Close" Style="{DynamicResource menu_TopMenu_MenuItem_Style}"/>
                <MenuItem Header="Open" Style="{DynamicResource menu_TopMenu_MenuItem_Style}"/>
            </Menu>
        </DockPanel>

#2 - 资源字典文件 - 样式- ma​​intheme.xaml - 我将我的样式放在一个单独的文件中,所以我可以动态更换主题

     <ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                                     x:Class="PaintApp.maintheme"
                                    xmlns:local="clr-namespace:PaintApp">
                
                
           <!--..........Only For Style and alignment if you dont care about the style ignore this....................................................-->  
                <!--#1 - Top Menu-DockPanel-->
                <Style x:Key="dockPanel_Menu_TopMenu_Style" TargetType="{x:Type DockPanel}">
                    <Setter Property="VerticalAlignment" Value="Top"/>
                    <Setter Property="Height" Value="20"/>
                </Style>
            
            
                
                
          
        
     <!--..........Only For Style and alignment if you dont care about the style ignore this....................................................-->  
                <!--#2-Top Menu-Menu-->
                <Style x:Key="menu_TopMenu_Style" TargetType="{x:Type Menu}">
                    <Setter Property="DockPanel.Dock" Value="Top"/>
                    <Setter Property="Background" Value="#FF3E434B"/>
                    <Setter Property="Foreground" Value="#FFFFFA9B"/>
                    <Setter Property="FontFamily" Value="Verdana"/>
                </Style>
            
         
    
       
            
                  
    <!--.........Override PopUp so it can close on Mouse Leave + Style ----------------------------------->            
                <!--#3-Top Menu - MenuItem-->
                <Style x:Key="menu_TopMenu_MenuItem_Style" TargetType="{x:Type MenuItem}">
                    <Setter Property="Template">
                        <Setter.Value>
                        
                        
                        <ControlTemplate x:Name="menuItem" TargetType="{x:Type MenuItem}">
                            <Border x:Name="templateRoot"  BorderThickness="1" CornerRadius="1"  SnapsToDevicePixels="True">
                                <Grid VerticalAlignment="Center">
                                    <Grid.ColumnDefinitions>
                                        <ColumnDefinition Width="Auto"/>
                                        <ColumnDefinition Width="Auto"/>
                                    </Grid.ColumnDefinitions>
                                    
                                    <ContentPresenter ContentTemplate="{TemplateBinding HeaderTemplate}" Content="{TemplateBinding Header}" Grid.Column="1" ContentStringFormat="{TemplateBinding HeaderStringFormat}" ContentSource="Header" Margin="{TemplateBinding Padding}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/>
                                   
                                    <Popup x:Name="PART_Popup" AllowsTransparency="True" Focusable="False"  IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}" PopupAnimation="None" Placement="Bottom">
                                        <Border x:Name="SubMenuBorder">
                                            <ScrollViewer x:Name="SubMenuScrollViewer" 
                                          Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}"
                                          Background="Blue" Margin="0" Padding="0">
                                                <Grid  RenderOptions.ClearTypeHint="Enabled">   
                                                    <Canvas HorizontalAlignment="Left" Height="0" VerticalAlignment="Top" Width="0">
                                                        <Rectangle x:Name="OpaqueRect" Stroke="#8a919c"  RadiusX="5" RadiusY="5" StrokeThickness="1" Height="{Binding ActualHeight, ElementName=SubMenuBorder}" Width="{Binding ActualWidth, ElementName=SubMenuBorder}">
                                                            <Rectangle.Fill>
                                                            <LinearGradientBrush StartPoint="0,0" EndPoint="1,1">
                                                                    <GradientStop Color="#FF404957" Offset="0.144"/>
                                                                    <GradientStop Color="#FF2B3F47" Offset="0.994"/>
                                                                </LinearGradientBrush>
                                                            </Rectangle.Fill>    
                                                        </Rectangle>
                                                    </Canvas>
                                                    <ItemsPresenter x:Name="ItemsPresenter" KeyboardNavigation.DirectionalNavigation="Cycle" Grid.IsSharedSizeScope="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" KeyboardNavigation.TabNavigation="Cycle" />
                                                </Grid>
                                            </ScrollViewer>
                                        </Border>    
                                    </Popup>
                                    
                                </Grid>
                            </Border>
        
                            
                            <ControlTemplate.Triggers>
                                <Trigger Property="IsSuspendingPopupAnimation" Value="True">
                                    <Setter Property="PopupAnimation" TargetName="PART_Popup" Value="None"/>
                                </Trigger>
                            
                                
                                <Trigger Property="IsKeyboardFocusWithin" Value="True">
                                    <Setter TargetName="templateRoot" Property="Background" Value="#FF576DB9" />
                                </Trigger>
        
        
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Background" TargetName="templateRoot" Value="#7F26DACA"/>
                                    <Setter Property="BorderBrush" TargetName="templateRoot" Value="#FF26DAB9"/>
        
                                    
                                    <Setter Property="IsOpen" TargetName="PART_Popup" Value="true"/>
                                    <Setter Property="Cursor" Value="Hand"/>
                                    <Setter Property="Focusable" Value="False"/>
                                </Trigger>
        
                              
                                   
                                
        
                                <!--On - MouseLeave - Close PopUp - "Menu" -->
                                <MultiTrigger>
                                    <MultiTrigger.Conditions>
                                        <Condition Property="IsKeyboardFocusWithin" Value="false" />
                                        <Condition Property="IsMouseOver" Value="false" />
                                    </MultiTrigger.Conditions>
        
                                    <MultiTrigger.Setters>
                                        <Setter Property="IsOpen" TargetName="PART_Popup" Value="false"/>
                                    </MultiTrigger.Setters>
                                </MultiTrigger>
        
                            </ControlTemplate.Triggers>
                        </ControlTemplate>
                        
                    </Setter.Value>  
                </Setter>
        
                
    
<!--......SubMenus....Only For Style and alignment if you dont care about the style ignore this....................................................-->             
        
                <!--Top - Menu - SUB - MenuItems-->
                <Style.Resources>
                    <Style TargetType="{x:Type MenuItem}">
                        <Setter Property="OverridesDefaultStyle" Value="True"/>
                        <Setter Property="SnapsToDevicePixels" Value="True"/>
                        <Setter Property="Template">
                            <Setter.Value>   
                                <ControlTemplate TargetType="{x:Type MenuItem}">
                                    <Border x:Name="subMenuitemBorder" BorderThickness="2" CornerRadius="3" SnapsToDevicePixels="True" Uid="Border_38">
                                        <Grid x:Name="bg"  Background="{TemplateBinding Background}">
                                            <ContentPresenter x:Name="HeaderHost" ContentSource="Header" RecognizesAccessKey="True">
                                                <ContentPresenter.ContentTemplate>
                                                    <DataTemplate>
                                                        <!--<Border BorderBrush="#FF60626A" BorderThickness="0, 0, 0, 1"  Margin="10, 0, 10, -5">-->
                                                        <TextBlock Padding="30, 3,30, 5"  Text="{Binding BindsDirectlyToSource=True}"/>
                                                        <!--</Border>-->
                                                    </DataTemplate>
                                                </ContentPresenter.ContentTemplate>  
                                            </ContentPresenter>    
                                        </Grid>
                                    </Border>
        
        
                                    
                                    <ControlTemplate.Triggers>
                                        <Trigger Property="IsHighlighted" Value="True">
                                            <Setter Property="BorderBrush" TargetName="subMenuitemBorder" Value="#FF26A0DA"/>
                                            <Setter Property="Background" TargetName="subMenuitemBorder" Value="#7F26A0DA"/>
                                        </Trigger>
                                    </ControlTemplate.Triggers>  
                                    
                                </ControlTemplate>    
                            </Setter.Value>  
                        </Setter>   
                    </Style>
                </Style.Resources>     
            </Style>
        
        
        
        
        
        
        
        <!--..........Only For Style and alignment if you dont care about the style ignore this....................................................--> 
        
            <!--Top - Menu Seperator-->
            <Style x:Key="menu_TopMenu_Seperator_Style" TargetType="{x:Type Separator}">
                <Setter Property="Background" Value="Red"/>
                <Setter Property="Margin" Value="10,1,10,1"/>
                <Setter Property="Focusable" Value="false"/>
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate TargetType="{x:Type Separator}">
                            <Border 
                                BorderBrush="#FF6A667E" 
                                BorderThickness="1" 
                                Background="Red"
                                Height="1" 
                                SnapsToDevicePixels="true"/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>

#3 - App.xaml 文件 - 因为我对样式使用单独的文件

<Application x:Class="PaintApp.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:PaintApp"
             StartupUri="MainWindow.xaml">


    <Application.Resources>

        <!--Seperate file for the styles-->
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="maintheme.xaml"></ResourceDictionary>
            </ResourceDictionary.MergedDictionaries>    
        </ResourceDictionary>   
        <!--Seperate file for the styles-->

    </Application.Resources>
</Application>