Статьи

Начало работы: Windows 8, MVVM Light и EventToCommand


Теперь, когда Windows 8 и Visual Studio находятся в RTM, я хотел бы составить краткий обзор для тех разработчиков Windows Phone, которые переходят на разработку Windows 8 с их навыками MVVM Light.

Лоран Бюньон, создатель инструментария MVVM Light, и я, как и многие другие, уже давно используем его для разработки Windows Phone. Я портирую свои приложения на Windows 8 и хотел перенести знания этого инструментария на новую платформу, надеясь, что появятся какие-то новые улучшения и / или не так много изменений, чтобы я мог просто пойти. Ну, это была сделка.

MVVM Light Toolkit для Windows 8 RTM


Последняя версия установщика для этого пакета, MVVM Light Toolkit V4 RTM, доступна на
CodePlex . Согласно блогу Лорана, он устанавливается бок о бок с предыдущими версиями:


MVVM Light для Windows 8 — это параллельная установка со стандартной бета-версией MVVM Light V3 или V4.
Просто скачайте и запустите MSI из Codeplex. Как обычно, последний шаг установки выполняет «/ setup» Visual Studio для актуализации кэша шаблона проекта, и, к сожалению, этот последний шаг может длиться очень долго. Пожалуйста, будьте терпеливы и не отменяйте до конца! Процесс установки очень похож на описанный на странице установки MVVM Light (за исключением того, что пока нет установщика NuGet для VS11).

Следующая
ссылка содержит сводную информацию о перенесенных компонентах из предыдущих версий, но я перефразирую здесь:

  • ObservableObject, включая все способы вызова PropertyChanged. 
  • ViewModelBase, включая все способы поднять PropertyChanged. 
  • Messenger, включая все типы сообщений, кроме DialogMessage (см. Ниже). 
  • RelayCommand с параметром и без него. 
  • SimpleIoc, который вполне может быть первым контейнером IOC, работающим в Windows 8. 

Человек я люблю
SimpleIoc ! Делает добавление новых видов намного проще, чем в версии для Windows Phone.

Есть несколько недостающих компонентов, одним из которых является
EventToCommand , однако благодаря новому другу, который у меня появился, Joost van Schaik (
см. Его блог здесь ), есть решение для этого, и он доступен в виде пакета nuget с некоторым дополнительным поведением. функции, которые я рекомендую вам изучить, но я по крайней мере расскажу о возможностях EventToCommand, которые он предлагает.

Начиная

Шаблон легкого проекта MVVM


После установки инструментария вы увидите, что в диалоговом окне «Новый проект» Visual Studio 2012 доступен новый шаблон проекта.
Отмечено как «Стиль Windows Metro»

Назовите проект «MvvmLight_Walkthrough» и нажмите «ОК».

Шаблон проекта прост, но добавляет некоторые новые функции, которых не было в предыдущих версиях инструментария. В обозревателе решений вы увидите
папку
Design с классом
DesignDataService . Это отличная особенность; шаблон по умолчанию, помещаемый в репозиторий классов данных проектирования.

Во-вторых, как и в прошлой версии инструментария, существует обычный
класс
ViewModelLocator , но в этой версии есть новая функция —
SimpleIoc , контейнерный класс, который, если вы похожи на меня, имеет все остальное в контейнере для DI, за исключением ViewModels, если вы не свернули свои собственные.

public class ViewModelLocator
 
    {
 
        static ViewModelLocator()
 
        {
 
            ServiceLocator.SetLocatorProvider(() => SimpleIoc.Default);
 
 
 
            if (ViewModelBase.IsInDesignModeStatic)
 
            {
 
                SimpleIoc.Default.Register<IDataService, Design.DesignDataService>();
 
            }
 
            else
 
            {
 
                SimpleIoc.Default.Register<IDataService, DataService>();
 
            }
 
 
 
            SimpleIoc.Default.Register<MainViewModel>();
 
        }
 
 
 
        /// <summary>
 
        /// Gets the Main property.
 
        /// </summary>
 
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance",
 
            "CA1822:MarkMembersAsStatic",
 
            Justification = "This non-static member is needed for data binding purposes.")]
 
        public MainViewModel Main
 
        {
 
            get
 
            {
 
                return ServiceLocator.Current.GetInstance<MainViewModel>();
 
            }
 
        }
 
 
 
        /// <summary>
 
        /// Cleans up all the resources.
 
        /// </summary>
 
        public static void Cleanup()
 
        {
 
        }

И наконец, в папке Model Лоран был достаточно любезен, чтобы также включить интерфейс IDataService и класс DataService, чтобы показать в примере, как использовать модели данных реального времени и времени разработки. Все они подключены в ViewModelLocator, как показано выше.

Теперь, если мы просто запустим приложение, вы должны получить следующее, чтобы убедиться, что все хорошо!

Бег в симуляторе

Как вы можете заметить или не заметить, это не должно отличаться от предыдущего теста шаблона проекта от предыдущей версии.

MainViewModel

Привязка ViewModel к представлению такая же, как и в предыдущей модели, и заметных изменений в ViewModelTemplate нет. Следует отметить, что все опции для RaisePropertyChanged включены в этот выпуск, где, как и в предыдущей версии, вам нужно было бы получить «предварительную» версию из nuget, чтобы использовать их. Например, встроенный шаблон добавляет следующее:

 

/// <summary>
 
        /// The <see cref="WelcomeTitle" /> property's name.
 
        /// </summary>
 
        public const string WelcomeTitlePropertyName = "WelcomeTitle";
 
 
 
        private string _welcomeTitle = string.Empty;
 
 
 
        /// <summary>
 
        /// Gets the WelcomeTitle property.
 
        /// Changes to that property's value raise the PropertyChanged event.
 
        /// </summary>
 
        public string WelcomeTitle
 
        {
 
            get
 
            {
 
                return _welcomeTitle;
 
            }
 
 
 
            set
 
            {
 
                if (_welcomeTitle == value)
 
                {
 
                    return;
 
                }
 
 
 
                _welcomeTitle = value;
 
                RaisePropertyChanged(WelcomeTitlePropertyName);
 
            }
 
        }
В тех случаях, когда RaisePropertyChanged использует строковое значение, одна из доступных в релизе опций — удалить   переменную WelcomeTitlePropertyName и затем изменить

RaisePropertyChanged(WelcomeTitlePropertyName);

к 

RaisePropertyChanged(() => WelcomeTitle);

Другим приятным преимуществом здесь является то, что шаблон также вставил проводку для внедрения IDataService в конструктор для ViewModel. Некоторые из этих маленьких вещей, которые мы, разработчики, либо считаем само собой разумеющимся, что кто-то пережил проблему с подключением сантехники, либо называют это скучной работой, которую необходимо выполнить, прежде чем мы закончим настоящую работу. Здесь вы можете легко поместить другие зависимости в конструктор, а затем просто добавить сопоставления в конструктор ViewModelLocator, просто зарегистрировав типы в контейнере SimpleIoc.

public MainViewModel(IDataService dataService)
 
        {
 
            _dataService = dataService;
 
            _dataService.GetData(
 
                (item, error) =>
 
                {
 
                    if (error != null)
 
                    {
 
                        // Report error here
 
                        return;
 
                    }
 
 
 
                    WelcomeTitle = item.Title;
 
                });
 
        }

Что теперь?.


Простым примером здесь является добавление некоторого содержимого в MainPage и просмотр пути перехода ко второму представлению.
Я не буду утомлять вас деталями добавления элементов управления на страницу, но вот как должна выглядеть страница, когда вы закончите. 
Добавил немного цвета MvvmLight для развлечения

EventToCommand


Теперь давайте просто добавим подсказку к кнопке отправки.
Но подождите, а где мой EventToCommand ??? Конечно, с помощью кнопки есть свойство Command, и вы можете установить его в ICommand во ViewModel, и все будет в порядке. Но существует множество элементов управления, как встроенных в WinRT, так и сторонних элементов управления, которые не имеют этого свойства. Итак, для простоты я использую этот элемент управления и верну EventToCommand обратно в ваш набор инструментов или в ваш Joostbox, я должен сказать.

Прочь в Nuget!


У меня была эта проблема, когда я искал поведение при портировании приложения, над которым я работал, и мог найти опасные варианты поведения в Blend, поэтому я пошел в nuget и провел некоторый поиск, и там не было ничего, что потрясало мое воображение.
Затем я натолкнулся на Джуста ван Шаика (
см. Его блог здесь ) и его библиотеку WinRTBehaviors, и так случилось, что я ударил его в середине загрузки пакета nuget для Win8nl.

Теперь это пакет Behaviors, который изначально был библиотекой Windows Phone 7, и теперь он развивается в своем собственном направлении и теперь содержит некоторые специфические для Windows 8 вещи (согласно nuget).
Итак, давайте установим это очень быстро.

Установите пакет, введя следующее в консоли диспетчера пакетов Nuget или выполнив поиск Win8nl в проводнике пакетов.


PM> Install-пакет Win8nl


Он добавит библиотеку и необходимые зависимости в проект, в том числе WinRTBehaviors.
Для получения дополнительной информации о других видах поведения 
посетите блог Joost .

Добавление EventToCommand 


Сначала давайте добавим ссылки на страницу XAML:
xmlns:WinRtBehaviors="using:WinRtBehaviors"
 
xmlns:Win8nl_Behavior="using:Win8nl.Behaviors"


Затем найдите элемент управления кнопки и добавьте следующее внутри кнопки XAML:

    <Button x:Name="btnSubmit" Content="Submit"    
 
                    FontFamily="{StaticResource MyFont}" FontSize="{StaticResource MyFontSize}"
 
                    HorizontalAlignment="Center" Margin="0,20,0,0">
 
 
 
                <WinRtBehaviors:Interaction.Behaviors>
 
 
 
                    <Win8nl_Behavior:EventToCommandBehavior Event="Tapped"      
 
                                                  Command="AreYouSureCommand"        
 
                                                  CommandParameter="{Binding MyName}"/>
 
 
 
                </WinRtBehaviors:Interaction.Behaviors>
 
 
 
            </Button>
Теперь откройте код MainViewModel.cs, и мы можем добавить команду для нового поведения здесь, когда кнопка нажата.

Как обычно, свойство Command ожидает ICommand, добавьте следующий код в MainViewModel и верните новый экземпляр RelayCommand для выполнения любого поведения, которое вы пожелаете. В этом примере я просто делаю небольшое всплывающее окно, чтобы показать все, что пользователь вводит в текстовое поле myName.

public ICommand AreYouSureCommand
 
        {
 
            get
 
            {
 
                return new RelayCommand<string>((p) =>
 
                {
 
 
 
                    var msg = new MessageDialog(string.Format("Hi there {0}", p));
 
                    
 
                    msg.ShowAsync();
 
 
 
                });
 
            }
 
        }

Смотрите результат здесь:

И это EventToCommand для MVVMlight для Windows 8!

В библиотеке WinRTBehaviors есть гораздо больше вариантов поведения, которыми вы должны воспользоваться, для меня наиболее заметными из них являются FlipViewPanoramaBehavior и NavigationService, портированные на Windows 8.