在WPF MVVM中处理大量命令

时间:2014-06-08 21:12:17

标签: c# wpf mvvm mvvm-light icommand

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

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

如果重要的是我使用MVVM Light的ICommand的RelayCommand实现。

我已经在一个更大的开源项目中看到了将它们放入集合中,并将这些集合分组到更多集合中...这些对我来说都显得非常混乱,但是上下文有点不同,就像所有这些命令一样绑定到菜单。我在这个应用程序中没有典型的下拉菜单,但我确实使用了许多不同的上下文菜单/按钮。

无论如何,从代码可读性/可维护性和功能角度来看,处理命令的一些想法是什么?

3 个答案:

答案 0 :(得分:1)

This post向您展示如何创建用于公开自定义命令的动态属性。您可以将其与反射混合以处理大量命令。

创建自定义属性:

[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 :(得分:1)

嗯...如果你看到它们会让你烦恼,那就把它们放在#region中并折叠该区域。建议把它们放在字典里的那个人,所以你只有一个看起来像维护头痛的属性......而且XAML绑定变得混乱。

答案 2 :(得分:0)

  

现在我的所有命令都在我的视图模型中列为属性,并在VM的构造函数中加载,或者延迟加载。

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

这样,您只需在Commands构造函数中创建并添加所有命令到ViewModel集合,甚至可以从ViewModel构造函数之外的工厂方法添加。

  

无论如何,从代码可读性/可维护性和功能角度来看,处理命令的一些想法是什么?

  1. 95%的案例无需区分ViewModel中的命令。

  2. 维护一个集合属性更容易,以便在ViewModel中维护大量属性。

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

  4. 在不更改现有类或子类的情况下向ViewModel添加命令的能力非常棒。