我正在尝试使用动态参数创建 RelayCommand 的实例:
public class RelayCommand<T> : ICommand
{
#region Declarations
private readonly Predicate<T> _canExecute;
private readonly Action<T> _execute;
#endregion
#region Constructors
/// <summary>
/// Initializes a new instance of the <see cref="RelayCommand<T>"/> class and the command can always be executed.
/// </summary>
/// <param name="execute">The execution logic.</param>
public RelayCommand(Action<T> execute)
: this(execute, null)
{
}
/// <summary>
/// Initializes a new instance of the <see cref="RelayCommand<T>"/> class.
/// </summary>
/// <param name="execute">The execution logic.</param>
/// <param name="canExecute">The execution status logic.</param>
public RelayCommand(Action<T> execute, Predicate<T> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
我有一个具有多种方法的 ViewModel,现在我只列出:
public void MyMethod(object parameter);
public bool CanMyMethod(object parameter);
我想将它们动态连接到 RelayCommand 的实例,如下所示:
ICommand command = new RelayCommand<ViewModel>((x)=>myviewmodel.MyMethod(myparameter),(x)=> myviewmodel.CanExecuteMyMethod(myparameter));
上一行有效,但是,我的方法名称是在运行时传入的,所以我需要动态地实现相同的目标。
编辑:只是一些澄清:在我的场景中,我不能直接按名称引用我的方法。我将用于创建 RelayCommand 的方法名称将作为字符串传递。
解决方案:
这是我使用@ZafarYousafi 建议的最终解决方案。请注意我如何为 RelayCommand 以及 Action 和 Predicate 使用通用的“对象”类型,因为这是我的方法参数(对象 myparameter)的类型:
object myparameter = //Some value gets assigned here.
Delegate td1 = null, td2 = null;
MethodInfo method1 = myviewmodel.GetType().GetMethod("MyMethodNameAsString");
if (tmethod1 != null)
td1 = Delegate.CreateDelegate(typeof(Action<object>), myviewmodel, method1);
MethodInfo tmethod = viewmodel.GetType().GetMethod("Can" + "MyMethodNameAsString");
if (method2 != null)
d2 = Delegate.CreateDelegate(typeof(Predicate<object>), myviewmodel, method2);
if (d1 != null && d2 != null)
{
item.Command = new RelayCommand<object>(obj => ((Action<object>) td1)(myparameter), obj => ((Predicate<object>)td2)(myparameter));
}
这应该相当于:
item.Command = new RelayCommand<object>(param=>myviewmodel.MyMethod(myparameter),param=>myviewmodel.CanMyMethod(myparameter));
重要提示:正如@DanC 所指出的,由 Josh Smith 创建的 RelayCommand 类不打算在创建时接收参数。在架构良好的 MVVM 解决方案中,RelayCommand 参数将通过 CommandParameter 属性的 XAML 绑定传递。因此,如果您将 button.Command 绑定到 RelayCommand,您还需要绑定 button.CommandParameter,如下所述:MVVM RelayCommand with parameters
旧不成功的尝试: 这是我到目前为止所拥有的:
Delegate d1 = null, d2 = null;
MethodInfo method1 = myviewmodel.GetType().GetMethod("MyMethodNameAsString");
if (method1 != null)
d1 = Delegate.CreateDelegate(typeof(Action<ViewModel>), myviewmodel, method1);
MethodInfo method2 = myviewmodel.GetType().GetMethod("Can" + "MyMethodNameAsString");
if (method2 != null)
d2 = Delegate.CreateDelegate(typeof(Predicate<ViewModel>), myviewmodel, method2);
if (d1 != null && d2 != null)
{
item.Command = new RelayCommand<ViewModel>((Action<ViewModel>)d1, (Predicate<ViewModel>)d2);
}
运行良好,没有编译或运行时错误,但是我不知道如何通过 RelayComand 构造函数参数传递我的参数。
任何建议将不胜感激,
谢谢
与我之前的问题有关