C# · 12月 26, 2021

c# – WPF – 如何使用绑定创建菜单和子菜单

我正在尝试使用绑定创建一个动态菜单.我的viewmodel我有一个包含头和命令的对象列表.但是,它不工作.我认为问题在数据模板中.请参阅我的代码: <Menu Background=”{x:Null}” Grid.Row=”0″ Grid.Column=”1″ Panel.ZIndex=”2″ Width=”865″ Height=”85″ HorizontalAlignment=”Left” ItemsSource=”{Binding Path=MenuItems}”> <Menu.ItemTemplate> <HierarchicalDataTemplate DataType=”MenuItemviewmodel” ItemsSource=”{Binding Path=MenuItems}”> <MenuItem Header=”{Binding Header}” Style=”{DynamicResource MenuItemStyle1}” ItemsSource=”{Binding Path=MenuItems}” Padding=”10,12,10,0″ Height=”44.1″ Margin=”30,0″ FontWeight=”Bold”> <MenuItem.ItemsPanel> <ItemsPanelTemplate> <VirtualizingStackPanel Orientation=”Horizontal”/> </ItemsPanelTemplate> </MenuItem.ItemsPanel> </MenuItem> <HierarchicalDataTemplate.ItemTemplate> <DataTemplate> <MenuItem Header=”{Binding Header}” Style=”{DynamicResource MenuItemStyle1}” Padding=”0,8,0″ Height=”38″> </MenuItem> </DataTemplate> </HierarchicalDataTemplate.ItemTemplate> </HierarchicalDataTemplate> </Menu.ItemTemplate> </Menu>

结果只显示第一个菜单.子菜单没有显示,但是它们在那里,因为有孩子的菜单,箭头在菜单标题后打印.

有没有人会发现绑定有问题?还是任何建议?

MenuItems是MenuItemviewmodel对象的列表,它有一个名为MenuItems的MenuItemviewmodel对象(子菜单)的头和列表.

解决方法 对我来说,它与这个简单的模板一起工作: <Menu.ItemContainerStyle> <Style TargetType=”{x:Type MenuItem}”> <Setter Property=”Command” Value=”{Binding Command}” /> </Style></Menu.ItemContainerStyle><Menu.ItemTemplate> <HierarchicalDataTemplate DataType=”{x:Type local:MenuItemviewmodel}” ItemsSource=”{Binding Path=MenuItems}”> <TextBlock Text=”{Binding Header}”/> </HierarchicalDataTemplate></Menu.ItemTemplate>

这是完整的例子:

MainWindow.xaml:

<Window x:Class=”WpfApplication14.MainWindow” xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation” xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml” xmlns:local=”clr-namespace:WpfApplication14″ Title=”MainWindow” Height=”350″ Width=”525″> <DockPanel> <Menu DockPanel.Dock=”Top” ItemsSource=”{Binding MenuItems}”> <Menu.ItemContainerStyle> <Style TargetType=”{x:Type MenuItem}”> <Setter Property=”Command” Value=”{Binding Command}” /> </Style> </Menu.ItemContainerStyle> <Menu.ItemTemplate> <HierarchicalDataTemplate DataType=”{x:Type local:MenuItemviewmodel}” ItemsSource=”{Binding Path=MenuItems}”> <TextBlock Text=”{Binding Header}”/> </HierarchicalDataTemplate> </Menu.ItemTemplate> </Menu> <Grid> </Grid> </DockPanel></Window>

MainWindow.xaml.cs:

using System;using System.Collections.ObjectModel;using System.Windows;using System.Windows.Input;namespace WpfApplication14{ public partial class MainWindow : Window { public ObservableCollection<MenuItemviewmodel> MenuItems { get; set; } public MainWindow() { InitializeComponent(); MenuItems = new ObservableCollection<MenuItemviewmodel> { new MenuItemviewmodel { Header = “Alpha” },new MenuItemviewmodel { Header = “Beta”,MenuItems = new ObservableCollection<MenuItemviewmodel> { new MenuItemviewmodel { Header = “Beta1” },new MenuItemviewmodel { Header = “Beta2”,MenuItems = new ObservableCollection<MenuItemviewmodel> { new MenuItemviewmodel { Header = “Beta1a” },new MenuItemviewmodel { Header = “Beta1b” },new MenuItemviewmodel { Header = “Beta1c” } } },new MenuItemviewmodel { Header = “Beta3” } } },new MenuItemviewmodel { Header = “Gamma” } }; DataContext = this; } } public class MenuItemviewmodel { private readonly ICommand _command; public MenuItemviewmodel() { _command = new Commandviewmodel(Execute); } public string Header { get; set; } public ObservableCollection<MenuItemviewmodel> MenuItems { get; set; } public ICommand Command { get { return _command; } } private void Execute() { // (NOTE: In a view model,you normally should not use Message@R_869_2419@.Show()). Message@R_869_2419@.Show(“Clicked at ” + Header); } } public class Commandviewmodel : ICommand { private readonly Action _action; public Commandviewmodel(Action action) { _action = action; } public void Execute(object o) { _action(); } public bool CanExecute(object o) { return true; } public event EventHandler CanExecuteChanged { add { } remove { } } }}

结果窗口如下所示: