我正在寻找有关在wpf mvvm项目中处理越来越多命令的建议.
我的视图模型正在收集大量的模型,我觉得在项目成熟之前我需要做一些更好的事情来处理它们.现在我的所有命令都只是在我的视图模型中列为属性,并且在VM的构造函数中加载,或者是延迟加载的.
如果重要的话,我正在使用MVVM Light的RelayCommand实现ICommand.
我已经看到一个更大的开源项目将它们放入集合中,并将这些集合分组到更多集合中…这对我来说似乎都很混乱,但是上下文有点不同,因为所有这些命令都绑定到菜单.我在这个应用程序中没有典型的下拉菜单,但我确实使用了许多不同的上下文菜单/按钮.
无论如何,从代码可读性/可维护性和功能角度来看,处理命令的一些想法是什么?
最佳答案
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));
}
}
}
可以轻松扩展此体系结构以支持在插件中定义命令.