我有一个名为RelayCommand
的类,它继承了这样定义的ICommand接口:
/// <summary>
/// Base command that executes an <see cref="Action"/>.
/// </summary>
public class RelayCommand : ICommand
{
#region Members
// The Action to run.
private Action mAction;
#endregion
#region Events
/// <summary>
/// Event fired when the value of <see cref="CanExecute(object)"/> changes.
/// </summary>
public event EventHandler CanExecuteChanged = (sender, e) => { };
#endregion
#region Constructor
/// <summary>
/// Default <see cref="RelayCommand"/> constructor.
/// </summary>
public RelayCommand(Action action)
{
mAction = action;
}
#endregion
#region Command Methods
/// <summary>
/// A <see cref="RelayCommand"/> can always be executed.
/// </summary>
/// <param name="parameter"></param>
/// <returns></returns>
public bool CanExecute(object parameter)
{
return true;
}
/// <summary>
/// Executes the <see cref="Action"/> of the command.
/// </summary>
/// <param name="parameter"></param>
public void Execute(object parameter)
{
mAction();
}
#endregion
}
我使用此类在整个应用程序中执行命令,有时需要执行Action
并在XAML中传递参数。问题是该参数传递是可选的,但是我找不到适合我正在执行的解决方案。例如,我有这三个命令基本上可以完成相同的操作。我通过UI将PriorityLevel
(enum
值)设置为对象,然后根据单击哪个控件,执行以下三种方法之一:
/// <summary>
/// What to do when the priority of the task is set to <see cref="PriorityLevel.Low"/>
/// </summary>
private void OnSetLowPriorityCommand()
{
Priority = PriorityLevel.Low;
PriorityGridWidth = 10;
PriorityFlagOpacity = 0;
mIsPriorityChanged = true;
}
/// <summary>
/// What to do when the priority of the task is set to <see cref="PriorityLevel.Medium"/>
/// </summary>
private void OnSetMediumPriorityCommand()
{
Priority = PriorityLevel.Medium;
PriorityGridWidth = 10;
PriorityFlagOpacity = 0;
mIsPriorityChanged = true;
}
/// <summary>
/// What to do when the priority of the task is set to <see cref="PriorityLevel.High"/>
/// </summary>
private void OnSetHighPriorityCommand()
{
Priority = PriorityLevel.High;
PriorityGridWidth = 10;
PriorityFlagOpacity = 0;
mIsPriorityChanged = true;
}
如您所见,除了方法的第一行之外,其余的都是相同的,但是我认为,如果我只保留一个称为SetPriorityCommand
的方法,那会更好。 switch
或其他任何值都可以设置正确的PriorityLevel
值。然后,我像这样消耗Action
:
SetLowPriorityCommand = new RelayCommand(OnSetLowPriorityCommand);
无论如何,在其他情况下,我无需传递参数即可执行Action
。
最后,在XAML中,我需要执行如下命令:
<Border.InputBindings>
<MouseBinding MouseAction="LeftClick"
Command="{Binding SetLowPriorityCommand}"
CommandParameter="{Binding Source={x:Static core:PriorityLevel.Low}}"/> <!-- NOT ALWAYS NECESSARY -->
</Border.InputBindings>
我找到了很多有关此问题的答案,但似乎没有一个使参数的使用成为可选项。
如何调整RelayCommand
类以适应我的需求?
预先感谢您的帮助。
答案 0 :(得分:1)
对代码的最简单的更改将只是使用一个object
参数,并在调用方法时进行强制转换。否则,您可以在网上搜索并找到RelayCommand<T>
的大量实现,但这是一个示例,该示例在您使用参数和不使用参数时都仅使用object
参数。
public class RelayCommand : ICommand
{
private Action<object> mAction;
public event EventHandler CanExecuteChanged = (sender, e) => { };
public RelayCommand(Action<object> action)
{
mAction = action;
}
public bool CanExecute(object parameter)
{
return true;
}
public void Execute(object parameter)
{
mAction(parameter);
}
}
public class ViewModel
{
//ignore the argument
private RelayCommand SetLowPriorityCommand { get => new RelayCommand(_ => SetLowPriority()); }
//cast and use the argument
private RelayCommand SetPriority { get => new RelayCommand(priority => SetPriority((int)priority)); }
private void SetLowPriority()
{
//....///
}
private void SetPriority(int priority)
{
//...//
}
}