3

Commanding в основном используется для четкого разделения между ViewModel и пользовательским интерфейсом. В чем разница между подпиской на события и commanding? Рассмотрим следующий пример:Xamarin.Forms: Подписка на обработчики событий VS. 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()?

ответ

5

Как правило, ваши команды будут существовать как свойства модели просмотра (как это предусмотрено в шаблоне проектирования MVVM). Они заключают в себе концепцию выполнения изолированных действий на модели просмотра или при переходе от одной модели просмотра к другой - например, во время навигационных действий. Это отделяет действие от вашего визуального интерфейса, что позволяет выполнять модульное тестирование этого кода. Кроме того, поскольку команда подключена в MVM через Bindings, вам не нужно беспокоиться о том, чтобы отменить подписку на события.

В сокращенном виде:

  • Команда, как правило, свойство вашей 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 содержит нулевой код, который работает с помощью визуальных элементов управления, и, таким образом, может быть очень легко протестированы. Кроме того, код класса App, который обрабатывает интерфейс, теперь намного проще.

Обычно я бы рекомендовал использовать разметку XAML, а не код для этого. Синтаксис Binding гораздо проще следовать в XAML, на мой взгляд.

Смежные вопросы