Windows Phone / [Из песочницы] Использование паттерна MVVM при создании приложений для Windows Phone

в 9:03, , рубрики: mvvm, windows phone 7, метки: , ,

Паттерн MVVM делится на три части:
Модель (Model), так же, как в классическом паттерне MVC, Модель представляет собой фундаментальные данные, необходимые для работы приложения.

Вид/Представление (View) так же, как в классическом паттерне MVC, Вид — это графический интерфейс, то есть окно, кнопки и.т.п.

Модель вида (ViewModel, что означает «Model of View») является с одной стороны абстракцией Вида, а с другой предоставляет обертку данных из Модели, которые подлежат связыванию. То есть она содержит Модель, которая преобразована к Виду, а так же содержит в себе команды, которыми может пользоваться Вид, чтобы влиять на Модель.

Зачастую возникает необходимость подписываться на события представления в модели представления или переопределять его методы (например, метод OnNavigatedFrom или OnNavigatedTo). Так как сам шаблон пропагандирует разделение логики и представления, писать в code behind уж очень не хочется.
Хочу продемонстрировать небольшой ToolKit, который можно взять за основу в небольших проектах, и немного облегчить процесс разработки.
Создаем базовый класс модели представления

public class BaseViewModel : INotifyPropertyChanged
{
#region Public Properties

public ProgressivePhoneApplicationPage View { get; set; }

#endregion

#region Public Methods

public void SetView(ProgressivePhoneApplicationPage view)
{
View = view;
View.Loaded += OnViewLoaded;
View.Unloaded += OnViewUnloaded;

View.NavigatedTo += OnNavigatedTo;
View.NavigatedFrom += OnNavigatedFrom;
}

public virtual void OnNavigatedTo(NavigationEventArgs args) { }

public virtual void OnNavigatedFrom(NavigationEventArgs args) { }

public virtual void OnViewUnloaded(object sender, RoutedEventArgs e) { }

public virtual void OnViewLoaded(object sender, RoutedEventArgs e) { }

#endregion

#region Implementation of INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged = delegate { };

public void NotifyPropertyChanged(string propertyName)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}

#endregion
}

ProgressivePhoneApplicationPage — это переопределенный класс PhoneApplicationPage, в котором реализован механизм поиска модели представления.
SetView() — метод для установки ссылки на представление, в модели представления.
Переопределяем класс PhoneApplicationPage

public class ProgressivePhoneApplicationPage : PhoneApplicationPage
{
public ProgressivePhoneApplicationPage()
{
DataContext = ViewModelFactory.Create(this);
}

public event Action NavigatedTo = delegate { };

public event Action NavigatedFrom = delegate { };

protected override void OnNavigatedTo(NavigationEventArgs e)
{
NavigatedTo(e);
base.OnNavigatedTo(e);
}

protected override void OnNavigatedFrom(NavigationEventArgs e)
{
NavigatedFrom(e);
base.OnNavigatedFrom(e);
}
}

В конструкторе мы используем класс-фабрику ViewModelFactory, задачей которого является поиск модели представления. Поиск осуществляется очень просто, если модель у нас называется LoginView, то соответствующий ей класс модели представления будем называть LoginViewModel. Это и будет критерием поиска.
Создаем класс фабрику для создания модели представления

public class ViewModelFactory
{
public static object Create(ProgressivePhoneApplicationPage view)
{
var viewModelType = FindViewModelType(view.GetType().Name);

if (viewModelType == null)
{
return new object();
}

object result = Activator.CreateInstance(viewModelType);
var methodInfo = result.GetType().GetMethod("SetView");
methodInfo.Invoke(result, new object[] { view });

return result;
}
}

Метод FindViewModelType, как видно из названия, будет искать тип модели представления в сборках приложения.фыв
Использование подобной конструкции позволяет нам в модели представления иметь ссылку на само представления, а так же привязывать контекст данных представления.Википедия

* - обязательные к заполнению поля


https://ajax.googleapis.com/ajax/libs/jquery/3.4.1/jquery.min.js