Объять необъятное, или как использовать несколько mvvm...

44

Upload: denis-tsvettsih

Post on 21-Mar-2017

239 views

Category:

Software


5 download

TRANSCRIPT

Page 1: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте
Page 2: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

#msdevcon

Community TrackОбъять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проектеДенис ЦветцихРуководитель проектов, IceRockDev

Page 3: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

#msdevcon

Цели

Зачем нужен MVVM

фреймворк

Как выбрать MVVM

фреймворк

Как использовать несколько

MVVM фреймворко

вЧем отличаются MVVM

фреймворкиКак выбрать MVVM

фреймворк для конкретной платформы

Какие MVVM фреймворки мы

использовали и для каких задач

Решение какой задачи упрощает

использование MVVM фреймворка

Page 4: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

4

ОпросКто считает, что использовать несколько MVVM нельзя?Кто считает, что использовать несколько MVVM можно, но не использовал?Кто использовал несколько MVVM в одном проекте?

Page 5: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

5

Зачем нужен MVVM фреймворк?НавигацияРеализация INPC (ViewModelBase)Команды Message Bus (EventAggregator, Messenger)

Page 6: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

6

Зачем нужен MVVM фреймворк?НавигацияРеализация INPC (ViewModelBase)Команды Message Bus (EventAggregator, Messenger)

Page 7: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

7

Подходы к навигацииView FirstViewModel First

Это не разные реализации паттерна MVVM,но разные подходы к навигации с использованием MVVM

Page 8: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

8

ViewFirst: показать новую формуСоздать ViewСоздать ViewModel для ViewView.DataContext = ViewModelИнициализировать ViewModel

Page 9: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

9

ViewFirst: показать новую формуNavigation.Show<ViewModel>(Value);илиNavigation.Show("View", Value);

Похоже на: http://address.ru/?arg=value

ViewFirst предлагает организовать навигацию аналогично веб-приложению

Page 10: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

10

ViewModelFirst: показать новую формуСоздать ViewModelИнициализировать ViewModelСоздать View для ViewModelView.DataContext = ViewModel

Page 11: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

11

ViewModelFirst: показать новую формуvar vm = Navigation.Get<ViewModel>();vm.Arg = Value;vm.Show();Аналогично окну WPF:var wnd = new Window();wnd.Arg1 = Value1;wnd.Show();

ViewModel First навигация аналогична навигации в настольных приложениях

Page 12: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

12

ViewFirst vs ViewModelFirstViewFirst ViewModelFirstСоздать View Создать ViewModelСоздать ViewModel Инициализировать ViewModel

Инициализировать ViewModel Создать ViewView.DataContext = ViewModel View.DataContext = ViewModel

Page 13: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

13

Выбор MVVM фреймворкаВыбираем MVVM фреймворк по реализованному подходу к навигацииНавигация MVVM фреймворка соответствует навигации в API выбранной технологииWPF: ViewModelFirst подход (MugenMvvmToolkit, ReactiveUI)UWP: ViewFirst подход (Prism)

Page 14: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

14

Какие задачи решает MVVM фреймворк?Навигация КомандыПривязкиНа уровне ViewModel: передача событий между ViewModelНа уровне View: Binding в XAML

Разные задачи можно решать при помощи разных фреймворков!

Page 15: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

15

Набор MVVM фреймворков для UWPНавигация – PrismСобственное расширение Prism для CompositeUI

Команды – ReactiveCommand из ReactiveUIПривязкиПривязки ViewModel: Не используем MessageBus (EventAggregator из Prism)Привязки ViewModel: ObservableForProperty, WhenAny из ReactiveUIПривязки View: альтернативный Binding из MugenMvvmToolkit

Page 16: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

16

Prism - ViewFirst навигацияpublic interface INavigationService{

bool Navigate(string pageToken, object param);void GoBack();void GoForward();void ClearHistory();

}

Page 17: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

17

Достоинства навигации PrismViewFirst подход, реализованный в Prism, соответствует API для навигации в UWPCompositeUI не реализован в Prism для UWP, но нужное решение есть по ссылкеhttps://github.com/denis-tsv/Prism.StoreApps.Extensions.Mvvm

Page 18: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

18

ReactiveUI: команды и ViewModel привязкиpublic class LoginViewModel //: INotifyPropertyChanged{ public string Login { get; set; } // PropertyChanged

public string Password { get; set; } // PropertyChanged

public ICommand LoginCommand { get; private set; }

}

Page 19: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

19

1. ObservableForProperty// ПодпискаIDisposable _subscription = this.ObservableForProperty(vm => vm.Login) .Subscribe(OnLoginChanged);

// Реакция на событиеprivate void OnLoginChanged (IObservedChange<LoginViewModel, String> change){ }

// Отписка_subscription.Dispose();

Page 20: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

20

1. ObservableForProperty// ПодпискаIDisposable _subscription = this.ObservableForProperty(vm => vm.Login) .Subscribe(OnLoginChanged);

// Реакция на событиеprivate void OnLoginChanged (IObservedChange<LoginViewModel, String> change){ }

// Отписка_subscription.Dispose();

Page 21: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

21

1. ObservableForProperty// ПодпискаIDisposable _subscription = this.ObservableForProperty(vm => vm.Login) .Subscribe(OnLoginChanged);

// Реакция на событиеprivate void OnLoginChanged (IObservedChange<LoginViewModel, String> change){ }

// Отписка_subscription.Dispose();

Page 22: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

22

1. ObservableForProperty// ПодпискаIDisposable _subscription = this.ObservableForProperty(vm => vm.Login) .Subscribe(OnLoginChanged);

// Реакция на событиеprivate void OnLoginChanged (IObservedChange<LoginViewModel, String> change){ }

// Отписка_subscription.Dispose();

Page 23: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

23

2. WhenAnyIDisposable _subscription = this.WhenAny( vm => vm.Login, vn => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value)) .Subscribe(OnCredentialsChanged);

Page 24: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

24

2. WhenAnyIDisposable _subscription = this.WhenAny( vm => vm.Login, vn => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value)) .Subscribe(OnCredentialsChanged);

Page 25: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

25

2. WhenAnyIDisposable _subscription = this.WhenAny( vm => vm.Login, vn => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value)) .Subscribe(OnCredentialsChanged);

Page 26: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

26

Достоинства ReactiveUI привязокУдобное решение типовых задач:Подписка на изменение одного свойстваПодписка на изменение нескольких свойств

Уменьшается количество инфраструктурного кода, связанного с подписками и отписками

Page 27: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

27

ReactiveCommandCanExecute == false, когда Логин и пароль пустыеВыполняется запрос аутентификации на сервер

Page 28: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

28

3. ReactiveCommandpublic LoginViewModel(ILoginService loginService){ _loginService = loginService;

var canExecute = this.WhenAny(vm => vm.Login, vm => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value));

Page 29: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

29

3. ReactiveCommandpublic LoginViewModel(ILoginService loginService){ _loginService = loginService; // Login(login, password)

var canExecute = this.WhenAny(vm => vm.Login, vm => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value));

Page 30: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

30

3. ReactiveCommandpublic LoginViewModel(ILoginService loginService){ _loginService = loginService;

var canExecute = this.WhenAny(vm => vm.Login, vm => vm.Password, (login, password) => !string.IsNullOrEmpty(login.Value) && !string.IsNullOrEmpty(password.Value));

Page 31: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

31

3. ReactiveCommand LoginCommand = ReactiveCommand.CreateAsyncTask (canExecute,

async _ => await _loginService.Login(Login, Password));

LoginCommand.Subscribe(OnLoginCompleted);} // of ctor

private void OnLoginCompleted(bool loginSuccessed){ }

Page 32: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

32

3. ReactiveCommand LoginCommand = ReactiveCommand.CreateAsyncTask (canExecute,

async _ => await _loginService.Login(Login, Password));

LoginCommand.Subscribe(OnLoginCompleted);} // of ctor

private void OnLoginCompleted(bool loginSuccessed){ }

Page 33: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

33

3. ReactiveCommand LoginCommand = ReactiveCommand.CreateAsyncTask (canExecute,

async _ => await _loginService.Login(Login, Password));

LoginCommand.Subscribe(OnLoginCompleted);} // of ctor

private void OnLoginCompleted(bool loginSuccessed){ }

Page 34: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

34

Достоинства ReactiveCommand Не нужно мониторить значения свойств Login и PasswordНе нужно мониторить начало и конец асинхронной операции логина

Page 35: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

35

Mugen: альтернативные XAML привязкиПримеры для TextBox.TextText Property, Mode=TwoWay, Validate=TrueText $string.Format('{0} {1}', Prop1, Prop2), Delay=100Text Property.MyCustomMethod()Text Prop1 ?? Prop2Text $CustomMethod(Prop1, Prop2, ‘string value’)Text Prop1 == ‘test’ ? Prop2 : ‘value’

Page 36: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

36

Достоинства XAML привязок из Mugen:Поддержка синтаксиса C#Операторы ??, ?:, +, -, *, /, %, , ==, !=, <, >, <=, >=, &&(and), ||(or), |, &, !,

Ключевые слова $self – текущий элемент$root – корневой элемент$context – текущий DataContext$args – текущий параметр EventArgs

Page 37: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

37

Недостаток Mugen привязокАльтернативная реализация Binding, которую нужно решиться использовать в продакшене

Page 38: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

38

Итоги: навигацияMVVM нужен для навигацииНавигация ViewFirstАналог навигации в веб-приложенияхУдобна для WinRT, UWPРеализована в Prism

Навигация ViewModelFirstАналог навигации в настольных приложенияхУдобна для WPF, SilverlightРеализована в MugenMvvmToolkit, ReactiveUI

Page 39: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

39

Несколько MVVM фреймворков для UWPНавигация – PrismКоманды – ReactiveUI Привязки ViewModel – ReactiveUI вместо MessageBus (EventAggregator)Привязки XAML – Mugen привязки вместо BindingPrism используется как MVVM фреймворк, Mugen и ReactiveUI – как библиотеки

Page 40: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

40

Особенности использования нескольких MVVM

ДостоинствоСоединяем преимущества всех MVVM фреймворков

НедостатокВ рамках CodeReview нужно следить за тем, что каждый MVVM используется только для своей задачи

Page 41: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

#msdevcon

Что дальше

Посмотреть сэмплы

ReactiveUI и Mugen

Начните с небольших

задачВыпилить

MessageBusReactiveUI – командыMugenMvvmToolkit –

привязки XAML

EventAggregator или Messenger заменить на

привязки уровня ViewModel

Вам понравится ))

Page 42: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

#msdevcon

Полезные ресурсы

MugenMvvmToolkithttps://github.com/MugenMvvmToolkithttps://habrahabr.ru/post/236745/

ReactiveUIhttp://reactiveui.net/https://github.com/reactiveui

Как реализовать CompositeUI без MessageBushttps://github.com/denis-tsv/Prism.StoreApps.Extensions.Mvvm

Page 43: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

#msdevcon

Q&AОбъять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проектеДенис Цветцих[email protected]

Page 44: Объять необъятное, или как использовать несколько MVVM фреймворков в одном XAML проекте

© 2016 Microsoft Corporation. All rights reserved.