Commanding主要用于在ViewModel和用户界面之间进行清晰的分隔。事件订阅和命令之间有什么区别?考虑以下示例:
public App ()
{
Button button = new Button
{
Text = "Press me",
};
button.Clicked += Button_Clicked;
// The root page of your application
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = {
button,
}
}
};
}
private void Button_Clicked(object sender, EventArgs e)
{
System.Diagnostics.Debug.WriteLine("Pressed!");
}
与。
public App ()
{
Button button = new Button
{
Text = "Press me",
};
button.Command = new Command(() => System.Diagnostics.Debug.WriteLine("Pressed!"));
// The root page of your application
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = {
button,
}
}
};
}
关于内存管理,应该取消订阅该活动。这也适用于指挥吗?应该在哪里订阅/取消订阅活动?在OnAppearing()
和OnDisappearing()
中?
通常,您的命令将作为视图模型的属性存在(如MVVM设计模式中所要求的)。它们封装了对视图模型执行隔离操作的概念,或者在从一个视图模型转换到另一个视图模式时执行隔离操作,例如在导航活动期间。这将操作与可视化界面解耦,从而实现代码的单元测试。此外,由于该命令是通过绑定在MVM中连接的,因此您不必担心取消订阅事件。
简而言之:
- 命令通常是ViewModel的属性,与上面的代码不同
- 它们可以通过编码的单元测试进行测试
- 它们通过Binding语法而不是事件处理程序附加到视觉元素
- 出于内存管理的目的,您不需要担心取消订阅它们——绑定不会固定与其关联的视图
这更像您的第二个示例:
public class ViewModel : INotifyPropertyChanged {
public event PropertyChangedEventHandler PropertyChanged;
private string _text;
public string Text {
get { return _text; }
private set {
if (_text != value ) {
_text = value;
OnPropertyChanged("Text");
}
}
}
public ICommand Cmd { get; private set; }
public ViewModel() {
Text = "Press me";
Cmd = new Command(() => {
System.Diagnostics.Debug.WriteLine("Pressed!");
Text = "Thanks!";
});
}
private void OnPropertyChanged(string propertyName) {
var handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
}
}
//.....
public App ()
{
Button button = new Button();
button.BindingContext = new ViewModel();
button.SetBinding(Button.TextProperty, "Text");
button.SetBinding(Button.CommandProperty, "Cmd");
// The root page of your application
MainPage = new ContentPage {
Content = new StackLayout {
VerticalOptions = LayoutOptions.Center,
Children = {
button,
}
}
};
}
请注意,ViewModel类不包含任何处理视觉控件的代码,因此可以非常容易地进行单元测试。此外,App类中处理UI的代码现在变得简单多了。
通常,我建议使用XAML标记,而不是为此编写代码。在我看来,绑定语法在XAML中更容易理解。