使用MVVM动态创建UI控件的上下文菜单命令

本文关键字:上下文 菜单 命令 控件 UI MVVM 动态 创建 使用 | 更新日期: 2023-09-27 18:12:50

希望这个问题不是太笼统,但我刚刚开始使用WPF,我对这个问题很感兴趣。

我正在开发一个使用动态创建控件的应用程序。然而,目前我无法弄清楚如何使命令创建并添加更多控件到当前窗口,因为命令仅在无法看到视图的ViewModel中创建时才有效。然而,我不能在XAML中保留所有内容,因为除了一些最初为空的堆栈面板外,所有控件都是动态的。但我觉得我错过了一些简单的东西。

这里是binding

<MenuItem Header="LabelMenuItem" Command="{Binding Path=SpawnLabel}"/>

这里是命令

 public ICommand SpawnLabel { get { return new DelegateCommand(OnSpawnLabel); } }

Delegate命令的工作原理类似于这里定义的relay命令。

public class DelegateCommand : ICommand
    {
        private readonly Action _command;
        private readonly Func<bool> _canExecute;
        public event EventHandler CanExecuteChanged
        {
            add { CommandManager.RequerySuggested += value; }

       remove { CommandManager.RequerySuggested -= value; }
    }
    public DelegateCommand(Action command, Func<bool> canExecute = null)
    {
        if (command == null)
            throw new ArgumentNullException();
        _canExecute = canExecute;
        _command = command;
    }
    public void Execute(object parameter)
    {
        _command();
    }
    public bool CanExecute(object parameter)
    {
        return _canExecute == null || _canExecute();
    }
}

这在视图模型中工作,但我不知道究竟如何使它在视图中工作(或在不违反MVVM原则的情况下与视图对话),以便我可以使用c#中创建的当前控件更改UI。

目前,当我这样做的时候,我得到一个BindingExpression路径错误,这是有意义的,但我不知道如何绑定它来寻找视图中的命令。

使用MVVM动态创建UI控件的上下文菜单命令

你通过事件间接地与UI通信,如果你改变一个属性,你触发PropertyChanged, UI将更新绑定,如果你改变一个集合,你触发CollectionChanged,一个新的控件被添加或旧的被删除。

重要的接口是INotifyPropertyChangedINotifyCollectionChanged,只需将ItemsControl(通过ItemsSource)绑定到视图模型中的ObservableCollection<T>,并在命令中添加到该集合(您可能需要使用ItemsControl.ItemTemplate为您的视图模型指定视图,具体取决于您使用的MVVM框架)。