【发布时间】:2018-10-15 20:00:56
【问题描述】:
我需要一个自定义菜单(AMTMenu 类继承菜单加上一些额外的 DependencyProperties)和一个带有动态子项的 MenuItem(实际上是一个汉堡按钮),因为这个菜单要在很多布局中重复使用。除此之外,它应该显示其他 5 个 TopLevel 菜单项,这些菜单项显示 DataContext 中包含的信息,没有附加任何子项和刷新按钮。它工作正常,除了当我单击汉堡包 MenuItem 时未显示的子菜单部分,因为我似乎无法正确绑定项目。这是我到目前为止的代码:
<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 集合以显示在汉堡菜单项弹出窗口上?
【问题讨论】:
-
您是否有一个视图模型来支持您的视图?在视图模型中,您可以定义一个 ObservableCollection,它可以在视图更新时通知视图
-
我愿意,但这与我的问题有什么关系?