我正在为一个wpf应用程序开发一些XAML,但是我遇到了一些麻烦,让它做我想做的事情。以下是我的XAML示例:
<!-- Tool Bar Tray -->
<ToolBarTray Name="toolBarTray1" DockPanel.Dock="Top">
<!-- File And Edit Tools -->
<ToolBar Name="toolBar1" Band="1" BandIndex="1">
<!-- Regular Items -->
<Button>A</Button>
<Button>B</Button>
<!-- Overflow Menu For Special Items -->
<MenuItem ToolBar.OverflowMode="Always" Header="Special Items">
<MenuItem Header="C"/>
<MenuItem Header="D"/>
</MenuItem>
</ToolBar>
</ToolBarTray>
当我点击工具栏的溢出按钮时,“特殊项目”菜单项旁边会出现一个小箭头,表示嵌套元素。但是,当我将鼠标悬停在“特殊项目”上或尝试单击它时,未显示MenuItems“C”和“D”。
我希望MenuItem只能在菜单之外工作,但为了以防万一,我试图做直截了当的事情。在菜单中包含这些MenuItem,相反,为此菜单提供ToolBar.OverflowMode =“Always”属性会产生一些不需要的样式。箭头不再存在,需要单击“特殊项目”条目以激活子菜单,子菜单定位看起来有点偏。
有谁知道发生了什么事?
编辑:向溢出添加菜单正在产生我所要求的(非常惊讶)。我所追求的是一种将顶级标题和项目转换为子菜单级别的方法。我已在MSDN上转向此控件模板示例以获取解决方案(如下所示)。
编辑,编辑: @gcores(评论讨论):真的吗?我错过了什么吗?
<ToolBar Name="toolBar1" Band="1" BandIndex="4">
<!-- Displayed Buttons -->
<Button>A</Button>
<Button>B</Button>
<!-- Special Items Menu -->
<Menu ToolBar.OverflowMode="Always" >
<MenuItem Style="{StaticResource MenuItemStyle}" Header="Special">
<MenuItem Header="C"/>
<MenuItem Header="D"/>
</MenuItem>
</Menu>
</ToolBar>
此代码段对我不起作用。我必须点击“特殊”才能显示子菜单。
答案 0 :(得分:2)
另一个解决方案是使用现有模板并使用SubmenuHeader的模板覆盖TopLevelHeader的模板。
<Style x:Key="MenuItemStyle" TargetType="{x:Type MenuItem}">
<Style.Triggers>
<Trigger Property="Role" Value="TopLevelHeader">
<Setter Property="Template"
Value="{StaticResource {x:Static MenuItem.SubmenuHeaderTemplateKey}}"/>
</Trigger>
</Style.Triggers>
</Style>
在顶级MenuItem中使用此样式。这应该简化你的代码。
修改强>: 你是对的,只有当你点击它时才会起作用(不知道我是怎么说服自己有效的,对不起:))。 它的功能就像一个TopLevelMenu,即使模板说不然,它很混乱。
我唯一想到的是添加一个触发器来显示IsMenuOver上的子菜单并处理Click事件,因此它什么都不做,但我不知道它会有多好用。
答案 1 :(得分:1)
经过更多阅读后,我正在使用的解决方案如下。
<!-- Resource Dictionary Stuff -->
<!-- Some Brushes -->
<SolidColorBrush x:Key="Brush_1"
Color="White" />
<LinearGradientBrush x:Key="Brush_2"
StartPoint="0 0"
EndPoint="0 1">
<GradientStop
Color="White"
Offset="0"/>
<GradientStop
Color="DarkSeaGreen"
Offset="1"/>
</LinearGradientBrush>
<SolidColorBrush x:Key="Brush_3"
Color="DarkOliveGreen"/>
<!-- Custom MenuItem - Top Level Header - Style 1 -->
<Style x:Key="MenuItem_TLH_Style1"
TargetType="MenuItem">
<!--<EventSetter Event="PreviewMouseDown" Handler="DoNothing"/>-->
<Setter Property="Template">
<Setter.Value>
<ControlTemplate x:Name="ControlTemplate"
TargetType="MenuItem">
<!-- A headered text that may display a submenu
on a trigger. This submenu is the host for a
menu item's items. -->
<Border x:Name="BoundaryBorder"
Background="{StaticResource Brush_1}"
BorderThickness="1">
<Grid x:Name="ContainerGrid">
<ContentPresenter x:Name="HeaderContent"
Margin="6 3 6 3"
ContentSource="Header"
RecognizesAccessKey="True"/>
<Popup x:Name="SubmenuPopup"
Placement="Bottom"
IsOpen="{TemplateBinding IsSubmenuOpen}"
AllowsTransparency="True"
Focusable="False"
PopupAnimation="Fade">
<Border x:Name="SubmenuBoundaryBorder"
SnapsToDevicePixels="True"
Background="{StaticResource Brush_1}"
BorderBrush="{StaticResource SolidBorderBrush}"
BorderThickness="1">
<StackPanel x:Name="ItemsStackPanel"
IsItemsHost="True"
KeyboardNavigation.DirectionalNavigation="Cycle"/>
</Border>
</Popup>
</Grid>
</Border>
<ControlTemplate.Triggers>
<!-- -->
<Trigger
Property="IsSuspendingPopupAnimation"
Value="true">
<Setter
TargetName="SubmenuPopup"
Property="PopupAnimation"
Value="Fade"/>
</Trigger>
<!-- On mouse-over, show the submenu and highlight the header. -->
<Trigger
Property="IsMouseOver"
Value="true">
<Setter
TargetName="BoundaryBorder"
Property="Background"
Value="{StaticResource Brush_2}"/>
<Setter
TargetName="BoundaryBorder"
Property="BorderBrush"
Value="{StaticResource Brush_3}"/>
<Setter
Property="IsSubmenuOpen"
Value="true"/>
<!-- sloppy? -->
<Setter
TargetName="SubmenuPopup"
Property="IsOpen"
Value="true"/>
</Trigger>
<Trigger
SourceName="SubmenuPopup"
Property="AllowsTransparency"
Value="true">
<Setter
TargetName="SubmenuBoundaryBorder"
Property="CornerRadius"
Value="0 0 4 4"/>
<Setter
TargetName="SubmenuBoundaryBorder"
Property="Padding"
Value="0 0 0 3"/>
</Trigger>
<!-- Visually indicate an unaccessible menu item. -->
<Trigger
Property="IsEnabled"
Value="false">
<Setter
Property="Foreground"
Value="{StaticResource DisabledForegroundBrush}"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<!-- ... -->
<!-- Inside a window XAML file -->
<!-- Tool Bar Tray -->
<ToolBarTray x:Name="toolBarTray1"
DockPanel.Dock="Top">
<!-- File And Edit Tools -->
<ToolBar x:Name="toolBar1"
Band="1" BandIndex="1">
<!-- Displayed Buttons -->
<Button x:Name="ButtonA"
Content="A"/>
<Button x:Name="ButtonB"
Content="B"/>
<!-- Overflow Menu For Special Items -->
<Menu x:Name="OverflowMenu"
ToolBar.OverflowMode="Always">
<MenuItem x:Name="SpecialsMenuItem"
Style="{StaticResource MyStyle}"
Header="Special Items">
<MenuItem x:Name="CMenuItem"
Header="C">
<MenuItem x:Name="DMenuItem"
Header="D"/>
</MenuItem>
</MenuItem>
</Menu>
</ToolBar>
</ToolBarTray>
我在鼠标悬停时攻击'SubmenuPopup'的行为,而不是处理click事件。我想更全面地理解这一点,所以我尝试注释掉触发器的这一部分,并在'PreviewMouseDown'事件中添加一个调用'DoNothing()'方法的事件处理程序。事实证明,我错过了一些东西,我认为它与聚焦和/或菜单如何处理其项目集合有关。在'DoNothing()'(routedEventArgs.Handled = true)之后不允许事件传播似乎消除了单击“特殊项目”菜单项时出现的问题。但是,如果导航离开菜单或添加了另一个菜单项然后单击它,则可以关闭或打开和关闭悬停行为。
答案 2 :(得分:0)
我发现甚至接近产生这种行为的唯一方法是在溢出中创建一个菜单,其中包含一个菜单项,其标题本身是另一个名为“Special Items”的菜单项,并包含正确的子项。它按预期工作,但看起来奇怪(这可以通过自定义模板补救),也似乎是一个巨大的黑客。我能想到的唯一“正确”的方法是制作你自己的类似MenuItem的控件,它会在盘旋时弹出一个ContextMenu或Popup,因为我不认为自定义ControlTemplate可以改变默认行为菜单,以免需要点击顶级项目。