【问题标题】:Xamarin.Forms: Subscribing to event handlers VS. commandingXamarin.Forms:订阅事件处理程序 VS。指挥
【发布时间】:2016-03-24 15:25:21
【问题描述】:

Commanding 主要用于在 ViewModel 和用户界面之间进行清晰的分离。事件订阅和commanding有什么区别?考虑以下示例:

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!");
}

VS.

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()

【问题讨论】:

    标签: c# memory-management xamarin event-handling xamarin.forms


    【解决方案1】:

    通常,您的命令将作为视图模型的属性存在(如 MVVM 设计模式中所要求的)。它们封装了在视图模型上执行隔离操作的概念,或者从一个视图模型转换到另一个视图模型 - 例如在导航活动期间。这将操作与您的可视界面分离,从而可以对该代码进行单元测试。此外,由于该命令是通过 Bindings 在 MVM 中连接起来的,因此您无需担心取消订阅事件。

    简而言之:

    • 命令通常是 ViewModel 的属性,与上面的代码不同。
    • 它们可以使用编码单元测试进行测试。
    • 它们通过绑定语法而不是事件处理程序附加到可视元素。
    • 您无需担心出于内存管理目的而取消订阅它们 - 绑定不会固定与其关联的视图。

    这更像是您的第二个示例的样子:

    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 类包含处理可视控件的零代码,因此可以很容易地进行单元测试。此外,处理 UI 的 App 类中的代码现在要简单得多。

    通常我会建议使用 XAML 标记而不是为此编写代码。在我看来,绑定语法在 XAML 中更容易遵循。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-06-15
      • 2021-03-29
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多