我需要具有一个带有动态子项的MenuItem(实际上是一个汉堡包按钮)的自定义Menu(继承菜单的AMTMenu类以及一些其他DependencyProperties),因为此菜单将在许多布局中重复使用。除此之外,它还应该显示其他5个TopLevel菜单项,这些菜单项显示了包含在DataContext上的信息,没有附加任何子项和一个刷新按钮。除我单击汉堡菜单项时未显示子菜单部分外,其他菜单项均正常运行,因为我似乎无法正确绑定项目。这是我到目前为止的代码:
<Menu.Template>
<ControlTemplate>
<Grid Name="ContentGrid"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"
IsItemsHost="True">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="HamburgerButtonColumn" Width="5*" />
<ColumnDefinition x:Name="ButtonsColumn" Width="90*" />
<ColumnDefinition x:Name="RefreshButtonColumn" Width="5*"/>
</Grid.ColumnDefinitions>
<MenuItem Foreground="{DynamicResource BlackBrush}"
Focusable="False"
Template="{DynamicResource MainMenuButtonTemplate}">
<MenuItem.Icon>
<iconPacks:PackIconMaterial Kind="Menu"
HorizontalAlignment="Left"
VerticalAlignment="Center"
MinHeight="20" />
</MenuItem.Icon>
</MenuItem>
<UniformGrid Name="ButtonsUniformGrid"
Grid.Column="1"
Columns="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:AMTMenu}}, Path=ButtonCount}"
Rows="1"
HorizontalAlignment="Stretch">
<MenuItem Grid.Column="0"
Template="{DynamicResource OiButtonsTemplate}"
Foreground="{Binding RelativeSource={RelativeSource Self}, Path=Tag, Converter={StaticResource OiMainMenuButtonsColorBrushConverter}}"
Focusable="False"
Command="{Binding ShowRefreshDataCommand}"
CommandParameter="Button1">
<MenuItem.Tag>
<MultiBinding Converter="{StaticResource MainMenuButtonsTextConverter}" ConverterParameter="INC">
[ ... MultiBinding logic ... ]
</MultiBinding>
</MenuItem.Tag>
</MenuItem>
[ ... XAML Code for the other 4 MenuItems ... ]
</UniformGrid>
<DockPanel Name="PART_Refresh"
Grid.Column="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
[ ... XAML Code for the refresh button ... ]
</DockPanel>
</Grid>
</ControlTemplate>
</Menu.Template>
关于汉堡菜单项,我有以下模板:
<ControlTemplate x:Key="MainMenuButtonTemplate"
TargetType="{x:Type MenuItem}">
<Grid SnapsToDevicePixels="true"
HorizontalAlignment="Stretch">
<StackPanel Background="{TemplateBinding Background}"
VerticalAlignment="Center"
HorizontalAlignment="Center">
<ContentControl x:Name="PART_Button"
Foreground="{TemplateBinding Foreground}"
Background="{TemplateBinding Background}"
Content="{TemplateBinding Icon}"
Focusable="False" />
</StackPanel>
<Popup x:Name="PART_Popup"
AllowsTransparency="true"
Focusable="false"
HorizontalOffset="1"
IsOpen="{Binding IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}"
PopupAnimation="{DynamicResource {x:Static SystemParameters.MenuPopupAnimationKey}}"
Placement="Bottom"
VerticalOffset="-1">
<Border BorderThickness="2"
BorderBrush="White"
Background="{TemplateBinding Background}">
<ScrollViewer x:Name="SubMenuScrollViewer"
CanContentScroll="true"
Style="{DynamicResource {ComponentResourceKey ResourceId=MenuScrollViewer, TypeInTargetAssembly={x:Type FrameworkElement}}}">
<Grid RenderOptions.ClearTypeHint="Enabled">
<ItemsPresenter x:Name="ItemsPresenter"
KeyboardNavigation.DirectionalNavigation="Cycle"
Grid.IsSharedSizeScope="true"
Margin="2"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
KeyboardNavigation.TabNavigation="Cycle"/>
</Grid>
</ScrollViewer>
</Border>
</Popup>
</Grid>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True">
<Setter Property="Foreground" Value="{DynamicResource AccentColorBrush}" TargetName="PART_Button"/>
<Setter Property="Background" Value="{DynamicResource GrayBrush}" TargetName="PART_Button"/>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
最后,我使用以下XAML声明菜单和子菜单:
<local:AMTMenu x:Name="MainMenu"
DockPanel.Dock="Top"
DataContext="{Binding CurrentModel}"
IsButton1Visible="True"
IsButton2Visible="True"
IsButton3Visible="True"
IsButton4Visible="True"
IsButton5Visible="False">
<MenuItem Header="Item 1" />
<Separator />
<MenuItem Header="Item 2" />
<Separator />
<MenuItem Header="Item 3" />
</local:AMTMenu>
如何绑定菜单上的Items集合以显示在汉堡MenuItem弹出窗口上?
答案 0 :(得分:0)
所以我发现了问题,在此发布以帮助有类似问题的任何人...问题是在模板上声明了汉堡菜单项,因此,菜单没有任何子项,因此未触发IsSubmenuOpen MenuItem上的属性。在意识到这一点之后,解决方案非常简单,用ItemsPresenter替换了模板上的MenuItem并将MenuItem移至Menu内容。另外,由于Menu现在在其类中定义了Items,所以我无法像以前一样声明子菜单,它将仅替换默认项,因此必须使用一个名为SubMenuItems的新DependencyProperty。
这是最终代码:
AMTMenu.xaml
<Menu>
<Menu.Template>
<ControlTemplate>
<Grid Name="ContentGrid"
Width="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Width}"
IsItemsHost="True">
<Grid.ColumnDefinitions>
<ColumnDefinition x:Name="HamburgerButtonColumn" Width="5*" />
<ColumnDefinition x:Name="ButtonsColumn" Width="90*" />
<ColumnDefinition x:Name="RefreshButtonColumn" Width="5*"/>
</Grid.ColumnDefinitions>
<ItemsPresenter x:Name="ItemsPresenter"
HorizontalAlignment="Center"
VerticalAlignment="Center"
KeyboardNavigation.DirectionalNavigation="Cycle"
Grid.IsSharedSizeScope="true"
SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"
KeyboardNavigation.TabNavigation="Cycle" />
<UniformGrid Name="ButtonsUniformGrid"
Grid.Column="1"
Columns="{Binding RelativeSource={RelativeSource AncestorType={x:Type local:AMTMenu}}, Path=ButtonCount}"
Rows="1"
HorizontalAlignment="Stretch">
<MenuItem Grid.Column="0"
Template="{DynamicResource OiButtonsTemplate}"
Foreground="{Binding RelativeSource={RelativeSource Self}, Path=Tag, Converter={StaticResource OiMainMenuButtonsColorBrushConverter}}"
Focusable="False"
Command="{Binding ShowRefreshDataCommand}"
CommandParameter="Button1">
<MenuItem.Tag>
<MultiBinding Converter="{StaticResource MainMenuButtonsTextConverter}" ConverterParameter="INC">
[ ... MultiBinding logic ... ]
</MultiBinding>
</MenuItem.Tag>
</MenuItem>
[ ... XAML Code for the other 4 MenuItems ... ]
</UniformGrid>
<DockPanel Name="PART_Refresh"
Grid.Column="2"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
[ ... XAML Code for the refresh button ... ]
</DockPanel>
</Grid>
</ControlTemplate>
</Menu.Template>
<MenuItem Foreground="{DynamicResource BlackBrush}"
Focusable="False"
Template="{DynamicResource MainMenuButtonTemplate}"
AllowDrop="True"
ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=local:AMTMenu}, Path=SubMenuItems}">
<MenuItem.Icon>
<iconPacks:PackIconMaterial Kind="Menu" MinHeight="20" />
</MenuItem.Icon>
</MenuItem>
</Menu>
父视图上的菜单声明:
<local:AMTMenu x:Name="MainMenu"
DockPanel.Dock="Top"
DataContext="{Binding CurrentModel}"
IsButton1Visible="True"
IsButton2Visible="True"
IsButton3Visible="True"
IsButton4Visible="True"
IsButton5Visible="False">
<local:AMTMenu.SubMenuItems>
<local:SubMenuItemsCollection>
<MenuItem Header="Item 1" />
<Separator />
<MenuItem Header="Item 2" />
<Separator />
<MenuItem Header="Item 3" />
</local:SubMenuItemsCollection>
</local:AMTMenu.SubMenuItems>
</local:AMTMenu>
其中SubMenuItemsCollection只是从ObservableCollection派生的类
public class SubMenuItemsCollection : ObservableCollection<FrameworkElement> { }
希望这对以后的人有所帮助;)