C# 在WPF MVVM中处理大量命令
我正在寻找关于在wpf mvvm项目中处理越来越多的命令的建议 我的viewmodels收集了很多,我觉得在项目成熟之前,我需要做一些更好的事情来处理它们。现在,我的所有命令都作为属性列在我的viewmodels中,要么加载到VM的构造函数中,要么延迟加载 如果有必要,我将使用MVVM Light的ICommand的RelayCommand实现 我在一个更大的开源项目中看到过将它们放入集合中,并将这些集合分组到更多集合中……对我来说,这一切看起来都很混乱,但上下文有点不同,因为所有这些命令都绑定到菜单。我在这个应用程序中没有典型的下拉菜单,但我使用了许多不同的上下文菜单/按钮 不管怎样,从代码可读性/可维护性以及功能的角度来看,关于处理命令有什么想法?演示如何创建动态属性以公开自定义命令。为了处理大量命令,可以将其与反射混合使用 创建自定义属性:C# 在WPF MVVM中处理大量命令,c#,wpf,mvvm,mvvm-light,icommand,C#,Wpf,Mvvm,Mvvm Light,Icommand,我正在寻找关于在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
构造函数之外的工厂方法中添加
不管怎样,从代码可读性/可维护性以及功能的角度来看,关于处理命令有什么想法
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个命令的唯一次数是当它是反模式时,即类似于上帝对象的东西。也许你的设计可以改进。