Недавно нашей командой (Sly Lamb) был выпущен клиент для сервиса Pruffi.ru под Windows Phone. Во время разработки у нас возник вопрос – как отображать пользователю список вакансий, который может находиться в нескольких состояниях.
В этой статье мы хотим показать легкий механизм изменения состояния отображения элементов при помощи Expression Blend и паттерна MVVM. Пример будет приведен с использованием фреймворка MVVM Light Toolkit, но думаю, различия с другими должны быть минимальны.
Итак, на панораме есть список вакансий. Он может загружаться, быть пуст, или отображаться. Первые два состояния можно объединить в одно визуальное – это вывод сообщения. Итого два состояния: показать список, показать сообщение.
Но как показать сообщение? Нехорошо пугать человека стандартными MessageBox-ами. Тогда, ориентируясь на стандартные приложения, мы решили убирать все элементы, и выводить сообщение на месте элементов. Мы поступили так же, как на скриншотах.
Первое, что приходит в голову, манипулировать свойствами Visiblity у всех элементов, в зависимости от состояния. Такой подход громоздкий, так как для переключения из одного состояния в другой надо будет написать функцию по скрытию и отображению нужных элементов, плюс надо будет самим инициировать эту функцию при нужных условиях.
Для данного случая Expression Blend приготовил нам удобный инструмент, это State(состояния) для каждого элемента, а также поведение DataStateBehavior.
State – это визуальное состояние элемента относительно базового, в котором хранятся параметры самого элемента и дочерних, такие как цвета, положения, прозрачность и т. д.
DataStateBehavior – это поведение, которое переключает между двумя State, в зависимости от условия. Если привязанный параметр совпадает со значением Value, тогда используется TrueState, если не совпадает, тогда FalseState.
Приведу небольшой пример, в котором создаются и переключаются по времени два состояния.
Создаем пустой проект, используя шаблон MvvmLight (WP71).
Шаблон входит в состав MVVM Light Toolkit.
Сразу создадим логику во ViewModel страницы MainPage. Добавим свойство, которое будет меняться каждые пять секунд с текста «ok» на «hello world».
Откроем MainViewModel.cs и создадим там свойство MessageText:
Чтобы свойство менялось каждые пять секунд, добавим в конструктор класса MainViewModel код:
Перейдем к дизайну страницы, для этого откроем проект в Expression Blend.
Добавим на MainPage кнопку и текстовый блок. Кнопку будем отображать, когда свойство MessageText равно «ok», во всех остальных случаях отображаем текстовое поле с содержимым MessageText.
Замечу, что кнопка играет роль контента страницы, а текстовое поле – некритичной ошибки или сообщения, при котором контент показывать нельзя или он пуст.
После добавления форма будет выглядеть примерно так.
К значению Text элемента TextBlock привязываем наше свойство MessageText, нажав на квадрат справа от свойства и выбрав пунк DataBinding. В открывшемся окне нужно выбрать нужное свойство и нажать «OK».
Перейдем к созданию состояний. Откройте вкладку States в панели, которая находиться в левом верхнем углу экрана. Нажмите в ней кнопку Add state group. Выберите состояние Base – это то, от которого буду отталкиваться все остальные.
Измените, свойство Visibility у текстового поля на Collapsed, чтобы оно пропало.
Нажмите справа у группы состояний VisualStateGroup кнопу Add State, чтобы создать состояние с название Normal, а затем c названием Message.
Состояние Normal оставим, т.к. оно должно быть таким же, как и Base. А состояние Message запишем, нажав на него. Должно появиться сообщение о записи как на скриншоте. После чего изменим свойство Visiblity у кнопки на Collapsed, а у текстового блока на Visiblity. Для завершения записи нажмите на одну из красных кнопок.
Состояния созданы, осталось добавить переключатель между ними. Для этого добавим на страницу DataStateBehavior из вкладки Assets в категории Behaviors.
Свойство Binding привязываем к свойству MessageText, значение Value выставляем в «ok». Состояние TrueState ставим Normal, а FalseState ставим Message. Запускаем приложение и видим, как меняется состояние страницы в зависимости от значения поля MessageText.
Также можно добавлять анимацию между состояниями или простые переходы через свойство Default transition в VisualStateGroup.
Еще хочется обратить ваше внимание на GoToStateAction, который умеет переходить на состояние при каком-либо действии, например при нажатии на кнопку.
На этом все, комментируйте, буду рад ответить на ваши вопросы.
Исходный код: скачать/посмотреть
В этой статье мы хотим показать легкий механизм изменения состояния отображения элементов при помощи Expression Blend и паттерна MVVM. Пример будет приведен с использованием фреймворка MVVM Light Toolkit, но думаю, различия с другими должны быть минимальны.
Для чего это нужно?
Итак, на панораме есть список вакансий. Он может загружаться, быть пуст, или отображаться. Первые два состояния можно объединить в одно визуальное – это вывод сообщения. Итого два состояния: показать список, показать сообщение.
Но как показать сообщение? Нехорошо пугать человека стандартными MessageBox-ами. Тогда, ориентируясь на стандартные приложения, мы решили убирать все элементы, и выводить сообщение на месте элементов. Мы поступили так же, как на скриншотах.
Как реализовать?
Первое, что приходит в голову, манипулировать свойствами Visiblity у всех элементов, в зависимости от состояния. Такой подход громоздкий, так как для переключения из одного состояния в другой надо будет написать функцию по скрытию и отображению нужных элементов, плюс надо будет самим инициировать эту функцию при нужных условиях.
Для данного случая Expression Blend приготовил нам удобный инструмент, это State(состояния) для каждого элемента, а также поведение DataStateBehavior.
State – это визуальное состояние элемента относительно базового, в котором хранятся параметры самого элемента и дочерних, такие как цвета, положения, прозрачность и т. д.
DataStateBehavior – это поведение, которое переключает между двумя State, в зависимости от условия. Если привязанный параметр совпадает со значением Value, тогда используется TrueState, если не совпадает, тогда FalseState.
Как использовать?
Приведу небольшой пример, в котором создаются и переключаются по времени два состояния.
Создаем пустой проект, используя шаблон MvvmLight (WP71).
Шаблон входит в состав MVVM Light Toolkit.
Сразу создадим логику во ViewModel страницы MainPage. Добавим свойство, которое будет меняться каждые пять секунд с текста «ok» на «hello world».
Откроем MainViewModel.cs и создадим там свойство MessageText:
public const string MessageTextPropertyName = "MessageText";
private string _messageText = "ok";
public string MessageText
{
get { return _messageText; }
set
{
if (_messageText == value)
return;
_messageText = value;
RaisePropertyChanged(MessageTextPropertyName);
}
}
Чтобы свойство менялось каждые пять секунд, добавим в конструктор класса MainViewModel код:
//создаем таймер
var dispatcherTimer = new System.Windows.Threading.DispatcherTimer();
//устанавливаем действие при каждом тике таймера
dispatcherTimer.Tick += ((a,b) =>
{
MessageText = MessageText == "ok" ? "hello world" : "ok";
});
//определяем интервал между тиками
dispatcherTimer.Interval = new TimeSpan(0, 0, 5);
//запускаем таймер
dispatcherTimer.Start();
Перейдем к дизайну страницы, для этого откроем проект в Expression Blend.
Добавим на MainPage кнопку и текстовый блок. Кнопку будем отображать, когда свойство MessageText равно «ok», во всех остальных случаях отображаем текстовое поле с содержимым MessageText.
Замечу, что кнопка играет роль контента страницы, а текстовое поле – некритичной ошибки или сообщения, при котором контент показывать нельзя или он пуст.
После добавления форма будет выглядеть примерно так.
К значению Text элемента TextBlock привязываем наше свойство MessageText, нажав на квадрат справа от свойства и выбрав пунк DataBinding. В открывшемся окне нужно выбрать нужное свойство и нажать «OK».
Перейдем к созданию состояний. Откройте вкладку States в панели, которая находиться в левом верхнем углу экрана. Нажмите в ней кнопку Add state group. Выберите состояние Base – это то, от которого буду отталкиваться все остальные.
Измените, свойство Visibility у текстового поля на Collapsed, чтобы оно пропало.
Нажмите справа у группы состояний VisualStateGroup кнопу Add State, чтобы создать состояние с название Normal, а затем c названием Message.
Состояние Normal оставим, т.к. оно должно быть таким же, как и Base. А состояние Message запишем, нажав на него. Должно появиться сообщение о записи как на скриншоте. После чего изменим свойство Visiblity у кнопки на Collapsed, а у текстового блока на Visiblity. Для завершения записи нажмите на одну из красных кнопок.
Состояния созданы, осталось добавить переключатель между ними. Для этого добавим на страницу DataStateBehavior из вкладки Assets в категории Behaviors.
Свойство Binding привязываем к свойству MessageText, значение Value выставляем в «ok». Состояние TrueState ставим Normal, а FalseState ставим Message. Запускаем приложение и видим, как меняется состояние страницы в зависимости от значения поля MessageText.
Также можно добавлять анимацию между состояниями или простые переходы через свойство Default transition в VisualStateGroup.
Еще хочется обратить ваше внимание на GoToStateAction, который умеет переходить на состояние при каком-либо действии, например при нажатии на кнопку.
На этом все, комментируйте, буду рад ответить на ваши вопросы.
Исходный код: скачать/посмотреть