在 WPF MVVM 中处理大量命令

问题描述 投票:0回答:4

我正在寻求有关处理 wpf mvvm 项目中越来越多的命令的建议。

我的视图模型收集了大量的模型,我觉得在项目成熟之前我需要做一些更好的事情来处理它们。 现在,我的所有命令都只是在我的视图模型中列为属性,并且要么加载到虚拟机的构造函数中,要么延迟加载。

如果重要的话,我正在使用 MVVM Light 的 ICommand 的 RelayCommand 实现。

我在一个更大的开源项目中看到将它们放入集合中,并将这些集合分组为更多集合......这对我来说似乎真的很混乱,但上下文有点不同,因为所有这些命令都绑定到菜单。 我在此应用程序中没有典型的下拉菜单,但我确实使用了许多不同的上下文菜单/按钮。

无论如何,从代码可读性/可维护性以及功能角度来看,处理命令有哪些想法?

c# wpf mvvm mvvm-light icommand
4个回答
1
投票

这篇文章向您展示如何创建动态属性来公开您的自定义命令。您可以将其与反射混合以处理大量命令。

创建自定义属性:

[AttributeUsage(AttributeTargets.Class)]
public class CommandClassAttribute : Attribute
{
    readonly string commandName;

    public CommandClassAttribute(string commandName)
    {
        this.commandName = commandName;
    }

    public string CommandName
    {
        get { return commandName; }
    }
}

然后用它标记您的所有命令:

[CommandClass("New")]
public class NewCommand : ICommand
{
    public bool CanExecute(object parameter)
    {
        return true;
    }

    public void Execute(object parameter)
    {
        MessageBox.Show("New");
    }

    public event EventHandler CanExecuteChanged;
}

然后您可以在应用程序启动时加载所有命令:

readonly Dictionary<string, ICommand> commands = new Dictionary<string, ICommand>();

void LoadCommands()
{
    Type[] types = Assembly.GetExecutingAssembly().GetExportedTypes();
    var iCommandInterface = typeof(ICommand);
    foreach (Type type in types)
    {
        object[] attributes = type.GetCustomAttributes(typeof(CommandClassAttribute), false);
        if (attributes.Length == 0) continue;
        if (iCommandInterface.IsAssignableFrom(type))
        {
            string commandName = ((CommandClassAttribute)attributes[0]).CommandName;
            commands.Add(commandName, (ICommand)Activator.CreateInstance(type));
        }
    }
}

此架构可以轻松扩展以支持在插件中定义命令。


1
投票

嗯...如果你觉得看它们很麻烦,那么把它们放在#region 中并折叠该区域。建议将它们放入字典中的人,这样你就只有一个属性,这对我来说似乎是一个令人头痛的维护...并且 XAML 绑定变得混乱。


0
投票

现在我的所有命令都只是在我的视图模型中列为属性,并且要么加载到虚拟机的构造函数中,要么延迟加载。

不要为

ViewModel
中的每个命令创建不同的属性,而是尝试创建单个集合属性
Commands
来保存
ViewModel
中的所有命令。

通过这种方式,您只需在

Commands
构造函数中创建所有命令并将其添加到
ViewModel
集合中,甚至可以从
ViewModel
构造函数外部的工厂方法创建所有命令。

无论如何,从代码可读性/可维护性以及功能角度来看,处理命令有哪些想法?

  1. 95% 的情况下无需区分

    ViewModel
    中的命令。

  2. 维护一个集合属性比在

    ViewModel
    中维护大量属性更容易。

  3. Commands
    集合可以轻松组合并映射到工具栏或分层上下文菜单。

  4. 在不更改现有类或子类化的情况下向

    ViewModel
    添加命令的能力真的很棒。


0
投票

我喜欢这种方法:

public ICommand MyCommand => new RelayCommand(
    () => { /* Command logic here */ },
    () => { /* CanExecute logic here */ }
);
© www.soinside.com 2019 - 2024. All rights reserved.