[英]RelayCommand best practice
I'm working with RelayCommands
(they are in a separate class) for about a month now and I got the feeling they're kind of clunky when declaring them. 我工作RelayCommands
(他们是在一个单独的类),现在约一个月,我得到了他们宣布他们的时候那种笨重是的感觉。 Below I have 3 ways I can think of how I can declare a RelayCommand
. 下面,我有3种方法可以考虑如何声明RelayCommand
。
In a first case I declare my ICommand
and then when the ViewModel is loading I construct my RelayCommand
that points to a method in my code. 在第一种情况下,我宣布我ICommand
,然后在视图模型加载我建立我的RelayCommand
这点在我的代码的方法。
public class MyViewModel
{
public ICommand MyCommand { get; private set; }
public MyViewModel()
{
MyCommand = new RelayCommand(MyMethod, CanMyMethod);
}
private void MyMethod()
{
// Do something here ...
}
private bool CanMyMethod()
{
return string.IsNullOrEmpty(MyString) ? false : true;
}
}
A second method is to do everything at once. 第二种方法是立即执行所有操作。
public ICommand MyCommand
{
get
{
return new RelayCommand(
() =>
{
// Do something here ...
},
() =>
string.IsNullOrEmpty(MyString) ? false : true);
}
}
Now, I'm planning to write an application with quite some Commands
in a certain ViewModel. 现在,我打算在某个ViewModel中编写带有很多Commands
的应用程序。 I also can't split the ViewModel in smaller ViewModels because all the controls
have to work together. 我也无法将ViewModel拆分为较小的ViewModel,因为所有controls
必须一起工作。
So my questions are: 所以我的问题是:
ICommands
? 声明和构造ICommands
的最佳方法是什么? Is it one of my approaches or is there an easier way? 这是我的方法之一还是有更简单的方法? ICommands
in a single ViewModel. 考虑到单个ViewModel中有50多个ICommands
,使用每种方法维护概述的难度有多大。 RelayCommands
I have to take in account if I'm only using .NET4.5? 如果仅使用.NET4.5,我必须考虑的RelayCommands
是否有任何限制? RelayCommands
I also found this project: Caliburn-Micro . 除了RelayCommands
之外,我还找到了这个项目: Caliburn-Micro 。 It allows you to do something like the code below. 它允许您执行类似以下代码的操作。 Does anyone have an idea how good this works performance wise in comparison to RelayCommands
? 有没有人知道与RelayCommands
相比,这在性能上有多好? This is just an extra question and not required to be answered to have a post marked as an answer. 这只是一个额外的问题,在帖子被标记为答案时不需要回答。 Xaml (View) Xaml(查看)
<Button x:Name="Login" Content="Log in" />
ViewModel 视图模型
public bool CanLogin(string username, string password)
{
return !String.IsNullOrEmpty(username) && !String.IsNullOrEmpty(password);
}
public string Login(string username, string password)
{
...
}
Refer below answers. 请参考以下答案。
Here's the pattern that I prefer, which is basically a variation of method 1: 这是我更喜欢的模式,基本上是方法1的变体:
public class MyViewModel
{
private readonly RelayCommand myCommand;
public MyViewModel()
{
this.myCommand = new RelayCommand(this.DoStuff, () => ...);
}
public ICommand MyCommand
{
get { return this.myCommand; }
}
private void DoStuff() { ... }
}
This has the advantage of keeping extra methods on your RelayCommand implementation (like RaiseCanExecuteChanged
) around for use from your view model, but exposes only an ICommand
instance to consumers. 这样做的好处是,可以在您的RelayCommand实现上保留其他方法(例如RaiseCanExecuteChanged
),以供您在视图模型中使用,但仅向使用者公开ICommand
实例。
I agree with Krowi, the first approach is much easier to read. 我同意Krowi的观点,第一种方法更容易阅读。 But I would put your relay command into its own class so you can re-use it: 但是我会将您的Relay命令放入其自己的类中,以便您可以重新使用它:
public class RelayCommand : ICommand
{
#region Fields
readonly Action<object> _execute;
readonly Predicate<object> _canExecute;
#endregion // Fields
#region Constructors
public RelayCommand(Action<object> execute)
: this(execute, null)
{
}
public RelayCommand(Action<object> execute, Predicate<object> canExecute)
{
if (execute == null)
throw new ArgumentNullException("execute");
_execute = execute;
_canExecute = canExecute;
}
#endregion
#region ICommand Members
[DebuggerStepThrough]
public bool CanExecute(object parameter)
{
return _canExecute == null ? true : _canExecute(parameter);
}
public event EventHandler CanExecuteChanged
{
add { CommandManager.RequerySuggested += value; }
remove { CommandManager.RequerySuggested -= value; }
}
public void Execute(object parameter)
{
_execute(parameter);
}
#endregion
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.