我建立在WPF的MVVM应用程序,我是一个菜单绑定到一个菜单项的模型。 我MenuItem类具有以下属性:
public class MenuItem
{
private List<MenuItem> _Items;
public MenuItem(string header, ICommand command)
{
Header = header;
Command = command;
}
public MenuItem()
{
}
public string Header { get; set; }
public List<MenuItem> Items
{
get { return _Items ?? (_Items = new List<MenuItem>()); }
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; }
}
这个菜单项的模型类是从数据库中的数据来填充。 在这种情况下,从数据库填充的唯一属性是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????
//e.g. item.Command = new RelayCommand(_MainViewModel.<item.CommandNameHere>, _MainViewModel."Can" + <item.CommandNameHere>
item.Command = new RelayCommand(_MainViewModel.OpenFile, _MainViewModel.CanOpenFile);
}
foreach(MenuItem child in item.Items)
{
RegisterMenuCommand(child);
}
}
顺便说一句,RelayCommand的签名是:
public RelayCommand(Action execute, Func<bool> canExecute)
是否有可能以实例我的反射或动态lambda表达式或类似的东西,这样我就可以用我的命令字符串的数据库会在运行时动态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<bool>),_MainViewModel, method2);
item.Command = new RelayCommand((Action)d1, (Func<bool>)d2);
}
foreach(MenuItem child in item.Items)
{
RegisterMenuCommand(child);
}
}
我使用.NET 4.0
谢谢!