Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/295.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 在WPF MVVM中处理大量命令_C#_Wpf_Mvvm_Mvvm Light_Icommand - Fatal编程技术网

C# 在WPF MVVM中处理大量命令

C# 在WPF MVVM中处理大量命令,c#,wpf,mvvm,mvvm-light,icommand,C#,Wpf,Mvvm,Mvvm Light,Icommand,我正在寻找关于在wpf mvvm项目中处理越来越多的命令的建议 我的viewmodels收集了很多,我觉得在项目成熟之前,我需要做一些更好的事情来处理它们。现在,我的所有命令都作为属性列在我的viewmodels中,要么加载到VM的构造函数中,要么延迟加载 如果有必要,我将使用MVVM Light的ICommand的RelayCommand实现 我在一个更大的开源项目中看到过将它们放入集合中,并将这些集合分组到更多集合中……对我来说,这一切看起来都很混乱,但上下文有点不同,因为所有这些命令都绑定

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

我的viewmodels收集了很多,我觉得在项目成熟之前,我需要做一些更好的事情来处理它们。现在,我的所有命令都作为属性列在我的viewmodels中,要么加载到VM的构造函数中,要么延迟加载

如果有必要,我将使用MVVM Light的ICommand的RelayCommand实现

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

不管怎样,从代码可读性/可维护性以及功能的角度来看,关于处理命令有什么想法?

演示如何创建动态属性以公开自定义命令。为了处理大量命令,可以将其与反射混合使用

创建自定义属性:

[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));
        }
    }
}
readonly Dictionary commands=new Dictionary();
void LoadCommands()
{
类型[]类型=Assembly.getExecutionGassembly().GetExportedTypes();
var iCommandInterface=类型(ICommand);
foreach(类型中的类型)
{
object[]attributes=type.GetCustomAttributes(typeof(CommandClassAttribute),false);
如果(attributes.Length==0)继续;
if(iCommandInterface.IsAssignableFrom(类型))
{
字符串commandName=((CommandClassAttribute)属性[0])。commandName;
Add(commandName,(ICommand)Activator.CreateInstance(type));
}
}
}
这种架构可以很容易地扩展,以支持在插件中定义命令

现在,我的所有命令都作为属性列在我的viewmodels中,要么加载到VM的构造函数中,要么延迟加载

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

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

不管怎样,从代码可读性/可维护性以及功能的角度来看,关于处理命令有什么想法

  • 95%的情况下,无需区分
    ViewModel
    中的命令

  • ViewModel
    中维护一个集合属性比维护许多属性更容易

  • 命令
    集合可以轻松合成并映射到工具栏或层次上下文菜单

  • ViewModel
    添加命令而不更改现有类或子类的功能非常强大


  • 嗯。。。如果你不想看它们,那么把它们放在一个区域,然后折叠该区域。那个建议把它们放在字典里的家伙,所以你只有一个财产,这对我来说似乎是一个维护难题。。。XAML绑定变得混乱。

    当我有很多命令时,我将它们放在一个称为XXXXCommanding的VM部分类中,其中XXXX是VM的名称。然而,我不赞成将它们放入收藏中。如果我需要迭代所有命令,我将使用反射。您是否考虑过您的ViewModels可能需要做很多工作?我在这方面与@CodeMonkey合作。错误地使用分部类在多个单独的文件中拆分巨型类只是隐藏了问题。此外,如果您发现自己在执行大量“工具栏”操作,如UI及其相应的命令(例如,考虑一个包含New、Edit、Save、Cancel、Delete等的CRUD屏幕)。考虑使用<代码> VistabeCelpEng/Eng>并以包含ItMeTimes的按钮实现UI作为<代码> ITEMsScript < /代码>。当有“组”命令时,我通常会这样做。你能给我们举一个这样的ViewModel及其许多命令的例子吗(例如,什么样的命令)?我这样问是因为我在每个视图模型中看到的超过3-4个命令的唯一次数是当它是反模式时,即类似于上帝对象的东西。也许你的设计可以改进。