c# - 如何在运行时使用MenuItems动态填充MenuItem?

标签 c# wpf mvvm menuitem

我有以下(简化的) View 模型:

public class ViewModel
{
    ObservableCollection<RackViewModel> Racks { get; set; }
}

public class RackViewModel
{
    public string Header { get; set; }

    public ICommand ActivateCommand { get; }

    public ICommand ShowInfoCommand { get; }
}

当然,viewmodel类实现了INotifyPropertyChanged,为简洁起见,我将其省略。我想在窗口的菜单栏中显示机架。我这样尝试过:
<Menu DockPanel.Dock="Top">
<MenuItem Header="Racks">
                <ItemsControl ItemsSource="{Binding Racks}">
                    <ItemsControl.ItemTemplate>
                        <ItemContainerTemplate>
                            <MenuItem Header="{Binding Header}">
                                <MenuItem Command="{Binding ActivateCommand}" Header="Activate"/>
                                <MenuItem Command="{Binding ShowInfoCommand}" Header="Show Information"/>
                            </MenuItem>
                        </ItemContainerTemplate>
                    </ItemsControl.ItemTemplate>
                </ItemsControl>
            </MenuItem>
</Menu>

这给了我以下结果:

enter image description here

当我将鼠标悬停在菜单上时,所有项目都被同时标记,并且我无法访问子菜单。我希望它是以下内容:

enter image description here

有人知道我做错了吗?

最佳答案

您可以使用ItemSource属性

看起来像:

    <Menu>
        <MenuItem Header="Click me" Command="{Binding ChangeCommand}"></MenuItem>
        <MenuItem Header="Items" ItemsSource="{Binding Items}">
            <MenuItem.ItemContainerStyle>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="Header" Value="{Binding Header}"></Setter>
                    <Setter Property="ItemsSource" Value="{Binding Children}"></Setter>
                    <Setter Property="Command" Value="{Binding Command}"></Setter>
                </Style>
            </MenuItem.ItemContainerStyle>
        </MenuItem>
    </Menu>

和您的ViewModel可能看起来像:
public class MainWindowViewModel
{
    public MainWindowViewModel()
    {
        Items = new ObservableCollection<MenuItem>();
        ChangeCommand = new RelayCommand(ChangeCollection);
        SomethingCommand = new RelayCommand(DoSomething);
    }

    private void DoSomething()
    {
        MessageBox.Show("Hello World");
    }

    private void ChangeCollection()
    {
        this.Items.Clear();

        Items.Add(new MenuItem{Header = "Test 1"});
        Items.Add(new MenuItem{Header = "Test 2", Command = SomethingCommand});
        Items.Add(new MenuItem{Header = "Test 3"});
    }

    public RelayCommand SomethingCommand {get; set;}
    public RelayCommand ChangeCommand { get; set; }

    public ObservableCollection<MenuItem> Items { get; set; }
}

MenuItem类:
public class MenuItem
{
    public MenuItem()
    {
        Children = new ObservableCollection<MenuItem>();
    }
    public string Header { get; set; }
    public ObservableCollection<MenuItem> Children { get; set; }
    public ICommand Command { get; set; }
}

要添加子项,只需选择要更改子项的MenuItem并将其添加或删除到该MenuItem.Children属性。

关于c# - 如何在运行时使用MenuItems动态填充MenuItem?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/60635346/

相关文章:

c# - 更改 XAML 文件后 Visual Studio 挂起

asp.net-mvc - ASP.NET 中的 Dapper、ODATA 和 IQueryable

c# - MSchart 极坐标图自定义标签不起作用

c# - 在 JSON 反序列化期间没有为 'System.String' 类型定义无参数构造函数

c# - WPF 与 C++,这可能吗?

c# - 在 WPF 中绘制动态多边形

c# - BrokeredMessage 已处置

c# - 为什么 GETDATE() 在 SSMS 和 C# Microsoft.Practices.EnterpriseLibrary.Data 上运行时会产生不同的结果?

c# - wpf 应用程序 mvvm 如何正确构建

c# - MVVM 模式、ObservableObject