我試圖創建一個RelayCommand與參數動態的實例:如何使用參數從lambda表達式創建委託?
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;
}
我有一個視圖模型有多種方法,現在我只是名單:
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的方法名稱將被視爲STRING。
SOLUTION:
這裏是我的最終解決方案,使用@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指出的那樣,由Josh Smith創建的RelayCommand類不打算在創建時接收參數。在架構良好的MVVM解決方案中,RelayCommand參數將通過CommandParameter屬性的XAML綁定傳遞。所以,如果你有一個綁定到一個RelayCommand你button.Command還需要綁定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構造函數參數。
任何意見將非常讚賞,
感謝
是RelayCommand的方法或類的名字嗎?請發佈完整的代碼 – Bond
它是一個類從Josh史密斯我相信,只是發佈它 –
你已經鍵入代理投入行動,現在你有充分的自由傳遞參數((行動)d1)(yourparameter) –
ZafarYousafi