如何通过动态reflection在运行时创建RelayCommand实例?

我正在WPF中构建MVVM应用程序,我将Menu绑定到MenuItem模型。 我的MenuItem类有以下属性:

public class MenuItem { private List _Items; public MenuItem(string header, ICommand command) { Header = header; Command = command; } public MenuItem() { } public string Header { get; set; } public List Items { get { return _Items ?? (_Items = new List()); } set { _Items = value; } } public ICommand Command { get; set; } public string CommandName { get; set; } public object Icon { get; set; } public bool IsCheckable { get; set; } public bool IsChecked { get; set; } public bool Visible { get; set; } public bool IsSeparator { get; set; } public string ToolTip { get; set; } public int MenuHierarchyID { get; set; } public int ParentMenuHierarchyID { get; set; } public string IconPath { get; set; } } 

此MenuItem模型类由来自数据库的Data填充。 在这种情况下,从DB填充的唯一属性是CommandName。

假设它用字符串“OpenFile”填充它

编辑这里我的MenuViewModelConstructor:

  public MenuViewModel(MainViewModel _MainViewModel) { .... } 

它依赖于MainViewModel,因为这是OpenFile和CanOpenFile方法所在的位置。

我的MenuViewModel有一个注册命令的方法,如下所示:

  private void RegisterMenuCommand(MenuItem item) { if(!string.IsNullOrEmpty(item.CommandName)) { //How can I create a new RelayCommand instance from //my CommandName string???? //eg item.Command = new RelayCommand(_MainViewModel., _MainViewModel."Can" +  item.Command = new RelayCommand(_MainViewModel.OpenFile, _MainViewModel.CanOpenFile); } foreach(MenuItem child in item.Items) { RegisterMenuCommand(child); } } 

顺便说一句,RelayCommand的签名是:

 public RelayCommand(Action execute, Func canExecute) 

是否可以使用Reflection或动态lambdas等实例化我的RelayCommand,以便我可以在运行时动态地使用来自数据库的命令字符串? 什么是最优化的方式?

编辑:解决方案感谢@Nathan指出我正确的解决方案,这是我的工作方法:

  private void RegisterMenuCommand(MenuItem item) { if(!string.IsNullOrEmpty(item.CommandName)) { MethodInfo method1 = _MainViewModel.GetType().GetMethod(item.CommandName); Delegate d1 = Delegate.CreateDelegate(typeof(Action),_MainViewModel, method1); MethodInfo method2 = _MainViewModel.GetType().GetMethod("Can" + item.CommandName); Delegate d2 = Delegate.CreateDelegate(typeof (Func),_MainViewModel, method2); item.Command = new RelayCommand((Action)d1, (Func)d2); } foreach(MenuItem child in item.Items) { RegisterMenuCommand(child); } } 

我使用的是.NET 4.0

谢谢!

我做了一个快速谷歌搜索创建代表与reflection,发现这篇相当不错的文章如何:使用reflection连接代表

我在我的本地机器上创建了一个快速测试并让它运行起来

 MethodInfo miHandler = typeof(MainWindow).GetMethod("OpenCommandHandler", BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); Delegate d = Delegate.CreateDelegate(typeof(Action), this, miHandler); btnTest.Command = new DelegateCommand((Action)d); 

CreateDelegate中的this是我正在使用的视图(MainWindow)

你需要调整一下才能让你的工作正常运行,但我想它会是这样的:

 var obj =  MethodInfo miHandler = typeof(obj).GetMethod(item.CommandName, BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Public); Delegate openDelegate = Delegate.CreateDelegate(typeof(Action), obj, miHandler); item.Command = new RelayCommand((Action)openDelegate, ...);