Я пытаюсь создать экземпляр 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));
предыдущая линия работает, однако, мои имена методы передается в во время выполнения, так Мне нужно добиться того же, но динамически.
EDIT: Только некоторые разъяснения: В моем сценарии я НЕ МОЖЕТ обращаться к моим методам по имени напрямую. Имя метода, которое я буду использовать для создания RelayCommand, будет выполнено как STRING.
РЕШЕНИЕ:
Вот мое окончательное решение, используя @ZafarYousafi предложение. Обратите внимание на то, как я использую универсальный тип «объект» для моего RelayCommand и действий и предиката, так что это тип моих параметров методов (объект 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, класс RelayCommand, созданный Джошем Смитом, не предназначен для получения параметров во время создания. В хорошо спроектированном MVVM-решении параметр RelayCommand передается через привязку XAML свойства CommandParameter. Так если у вас есть button.Command привязанный к RelayCommand также необходимо связать button.CommandParameter, как описано here: MVVM RelayCommand with parameters
OLD неудачная попытка: Это то, что я до сих пор:
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.
Любые советы будут очень признательны,
Благодаря
, относящиеся к моей previous question
ли RelayCommand имя метода или класса? отправьте полный код – Bond
это класс от Джоша Смита, я верю, только что опубликовал его –
u набрал команду делегата в действие, и теперь у вас есть полная свобода для передачи параметров ((Действие) d1) (yourparameter) –
ZafarYousafi