- •Разделы дисциплины и виды занятий в часах
- •Общая информация о курсе
- •Введение
- •Об авторах
- •Лекция 1. Краткое знакомство с моделью программирования xaml.
- •Краткий экскурс в историю графических интерфейсов пользователя
- •Windows Presentation Foundation – три в одном
- •Декларативное программирование ui и xaml
- •Основы модели ui и xaml
- •Элементы xaml
- •Элементы управления
- •Графические примитивы
- •Службы документов
- •Преобразования и анимация
- •Ресурсы и стили
- •Разделение труда дизайнера и разработчика
- •Xaml – текущая поддержка
- •Модель программирования xaml
- •Ключевые термины
- •Краткие итоги
- •Xaml подчиняется всем правилам wellformed xml, в частности это означает, что xaml документ:
- •Вариант 2 Задачи 3.
- •Вариант 2 Задачи 8.
- •Вариант 3 Задачи 8.
- •Xaml может использоваться для описания ui:
- •Xaml может использоваться:
- •Лабораторная работа 1. Размещение элементов управления.
- •Задания для самостоятельного выполнения
- •Учебный элемент. Создание нового проекта для Silverlight в VisualStudio 2010.
- •Шаг 1. Создание проекта
- •Шаг 2. Добавляем элементы интерфейса для xaml-страниц
- •Учебный элемент. Silverlight: размещение элементов.
- •Шаг 1. Принципы разметки
- •Шаг 2. Создаем Twitter-приложение
- •Шаг 3. Навигация
- •Шаг 4. Размещаем элементы для страницы поиска
- •Шаг 5. Изменяем UriMapper для Search.Xaml
- •Краткие итоги
- •Литература
- •Лекция 2. Сведения о wpf и Silverlight: Введение и архитектура платформ.
- •Независимость от разрешения
- •Архитектура Silverlight
- •Состав ядра представления:
- •В подмножество .Net Framework входят:
- •Архитектура wpf
- •Иерархия классов
- •Элементы управления wpf
- •Компоновочные элементы управления в системе wpf
- •Ключевые термины
- •Краткие итоги
- •Лекция 3. Стили и шаблоны элементов управления wpf.
- •Создание стиля
- •Использование стиля
- •Размещение стилей
- •Основы шаблонов
- •Создание шаблона
- •Повторное использование шаблона Control’а
- •Связывание в Шаблонах
- •Установка шаблонов через стили
- •Повторное использование настроек цвета
- •Ключевые термины
- •Краткие итоги
- •Вариант 2 Задачи 5.
- •Задания для самостоятельного выполнения
- •Учебный элемент. Стили и ресурсы в wpf
- •Шаг 1. Применение стиля в xaml документе
- •Шаг 2. Динамическое применение стилей в коде приложения
- •Поддержка множества целевых платформ
- •Клиентский профиль .Net
- •Визуальный конструктор Visual Studio
- •Графика Шейдеры
- •Кеширование графики
- •Новые функции для анимации
- •Усовершенствования двухмерной графики.
- •Поддержка Generics
- •Ключевые термины
- •Краткие итоги
- •Набор для практики
- •Литература
- •Лекция 5. Silverlight и wpf в Visual Studio 2010 (продолжение).
- •Новые возможности Silverlight 4. Silverlight 5: основные нововведения ожидаемого релиза. Хронология Silverlight
- •Связывание с данными Отладка
- •Поддержка Full-Trust внутри браузера
- •Обработка множественного нажатия кнопки мыши
- •Поддержка выбора элементов в ItemsControl с клавиатуры
- •Повышение полномочий для приложений в браузере
- •Поддержка нескольких окон
- •Доступ к файловой системе для приложений с повышенными привилегиями
- •Установка имени файла по умолчанию в SaveFileDialog
- •Улучшение работы с аудио
- •Изменение скорости проигрывания медиа
- •Поддержка пульта дистанционного управления
- •Работа с текстом
- •Отладка при связывании с данными
- •Улучшенная поддержка шаблона mvvm
- •Использование связывания в стилях
- •Неявные шаблоны
- •Другие изменения
- •Краткие итоги
- •Вариант 2 Задачи 2.
- •Вариант 2 Задачи 4.
- •Вариант 2 Задачи 6.
- •Вариант 3 Задачи 6.
- •Литература
- •Лекция 6. Привязка данных в технологиях wpf и Silverlight
- •Принципы работы с данными
- •Модель данных в .Net
- •Всепроникающее связывание
- •Преобразование данных
- •Ресурсы
- •Основные принципы связывания
- •Привязка к объектам clr
- •Редактирование
- •Ключевые термины
- •Вариант 2 Задачи 5.
- •Шаг 1. Создание повторно используемой функциональности
- •Устанавливаем стили для элементов управления
- •Двусторонняя привязка данных
- •Шаг 2. Добавление обработки событий клавиатуры
- •Шаг 3. Инкапсуляция разметки и логики в элемент управления UserControl
- •Реализация элемента управления
- •Добавление кода
- •Использование пользовательского элемента управления
- •Многократное использование
- •Шаг 1. Рефакторинг кода адресной формы
- •Код внутри класса AdressCustomControl
- •Определение свойств зависимости
- •Шаг 2. Рефакторинг кода разметки указателя цвета
- •Шаг 3. Оптимизация шаблона элемента управления
- •Манипулирование частями шаблона
- •Документирование частей шаблона
- •Ключевые термины
- •Вариант 2 Задачи 3.
- •Вариант 3 Задачи 3.
- •Задача 4. Вариант 1 Задачи 4.
- •Вариант 2 Задачи 4.
- •Вариант 3 Задачи 4.
- •Задача 5. Вариант 1 Задачи 5.
- •Вариант 2 Задачи 5.
- •Вариант 3 Задачи 5.
- •Задача 6. Вариант 1 Задачи 6.
- •Вариант 2 Задачи 6.
- •Вариант 3 Задачи 6.
- •Задача 7. Вариант 1 Задачи 7.
- •Вариант 2 Задачи 7.
- •Вариант 3 Задачи 7.
- •Литература
- •Лабораторная работа 3. Пользовательские элементы управления.
- •Задания для самостоятельного выполнения
- •Учебный элемент. Создание пользовательского элемента управления средствами дизайнера VisualStudio Шаг 1. Создание Silverlight проекта
- •Шаг 2. Создание пользовательского элемента управления
- •Шаг 5. Использование Custom Control
- •Учебный элемент. Создание пользовательского элемента управления средствами дизайнера Expression Blend
- •Шаг 1. Инкапсуляция ui в User Control
- •Шаг 2. Привязка адресов к нашему AddressUserControl – контроллеру.
- •Краткие итоги
- •Литература
- •Лекция 8. Использование событий, команд и триггеров в технологиях wpf и Silverlight
- •Принципиальные основы действий
- •Композиция элементов
- •Слабая связь
- •Декларативные действия
- •События
- •Команды
- •Команды и привязка к данным
- •Триггеры
- •Добавление триггеров к данным
- •Добавление триггеров к элементам управления
- •Вариант 2 Задачи 2.
- •Вариант 2 Задачи 6.
- •Вариант 2 Задачи 8.
- •Вариант 3 Задачи 8.
- •Литература
- •Лабораторная работа 4. Использование команд в технологиях wpf и Silverlight
- •Задания для самостоятельного выполнения
- •Учебный элемент. Использование стандартных и нестандартных команд Шаг 1. Использование стандартных команд.
- •Шаг 2. Использование нестандартных команд.
- •Шаг 3. Перевод команд из неактивного состояния в активное и обратно.
- •Краткие итоги
- •Литература
- •Лекция 9. Применение паттерна mvvm как оптимального при проектировании wpf и Silverlight приложений
- •Паттерн Model-View-ViewModel (mvvm)
- •Обязанности и характеристики классов.
- •Класс представления (View).
- •Класс модели представления (View Model).
- •Представление или Модель Представления?
- •Класс модели (Model).
- •Взаимодействие классов.
- •Привязка данных.
- •Реализация iNotifyPropertyChanged.
- •Реализация iNotifyCollectionChanged.
- •Реализация iCollectionView.
- •Команды.
- •Реализация Command Objects.
- •Подтверждение правильности данных и сообщение об ошибках.
- •Реализация iDataErrorInfo.
- •Создание и соединение.
- •Создание модели представления через xaml.
- •Создание модели представления программно.
- •Создание представления, определенного как шаблон данных.
- •Вариант 2 Задачи 1.
- •Вариант 3 Задачи 1.
- •Задача 2. Вариант 1 Задачи 2.
- •Вариант 2 Задачи 2.
- •Вариант 3 Задачи 2.
- •Задача 3. Вариант 1 Задачи 3.
- •Вариант 2 Задачи 3.
- •Вариант 2 Задачи 6.
- •Вариант 3 Задачи 6.
- •Задача 7. Вариант 1 Задачи 7.
- •Вариант 2 Задачи 7.
- •Вариант 3 Задачи 7.
- •Литература
- •Лабораторная работа 5. Реализация wpf проекта с помощью mvvm toolkit’а
- •Задания для самостоятельного выполнения
- •Учебный элемент. Реализация паттерна mvvm средствами Model-View-ViewModel Toolkit 0.1
- •Шаг 1. Постановка задачи
- •Шаг 4. Редактирование
- •Шаг 5. Команды
- •Краткие итоги
- •Литература
- •Лекция 10. Проектирование приложения с учетом использования единого опыта разработки для настольных и Web-проектов.
- •Подходы к решению задачи
- •Разработка кроссплатформенного проекта с самого начала
- •Разработка для одной платформы с последующим портированием на другую
- •Инструментарий
- •Создание ссылок на файлы в Visual Studio
- •Создание ссылок на xaml файлы
- •Директивы препроцессора
- •Разделяемые классы
- •Синхронное использование xaml
- •Решение проблем недостающего функционала Отсутствие FrameworkPropertyMetadata
- •Отсутствие приведения значения
- •Отсутствие метода OverrideMetadata()
- •Отсутствие зависимых свойств только для чтения
- •Отсутствие класса Brushes
- •Конструкторы по умолчанию для геометрий
- •Отсутствие свойства No PathSegment.IsStroked
- •Краткие итоги
- •Принцип инверсии зависимостей
- •Формы инверсии зависимостей
- •IoC контейнер
- •Определение моделей представления
- •Определение представлений
- •Сопоставление модели представления и представления
- •Реализация iNotifyPropertyChanged средствами аспектно-ориентированного программирования
- •Краткие итоги
- •IoC контейнер в mef инкапсулируется классом …
- •Понятие iChildViewModelManager
- •Реализация ChildViewModelBase
- •Реализация ModalChildViewModelBase
- •Реализация MessageViewModel
- •Краткие итоги
- •Литература Лабораторная работа 6. Построение кроссплатформенного Silverlight/wpf приложения.
- •Создание проектов
- •Краткие итоги
- •Список литературы
Редактирование
Чтобы редактировать значения, должен быть какой-то способ узнать, что значение изменилось. Помимо разрешения изменять свойство, существует несколько интерфейсов, которые позволяют объекту или списку рассылать извещения об изменении. Если источник данных уведомляет об изменении, то система связывания сможет отреагировать на модификацию данных. Чтобы наделить наш класс Person способностью извещать об изменениях, у нас есть три возможности:
реализовать интерфейс INotifyPropertyChanged;
добавить события, с помощью которых мы будем сообщать об изменении;
создать свойства, производные от класса DependencyProperty.
Использование событий для извещения об изменениях свойств впервые было применено в .NET 1.0 и поддерживается механизмами связывания в Windows Forms и ASP.NET. Интерфейс INotifyPropertyChanged появился в .NET 2.0. Он оптимизирован для привязки к данным, обладает более высокой производительностью и проще как для авторов объектов, так и для самой системы связывания. Но использовать этот интерфейс в обычных сценариях, когда необходимо извещать об изменениях, несколько сложнее.
Применение свойств, производных от DependencyProperty, относительно просто, позволяет объекту воспользоваться преимуществами, которые дает разреженное хранилище, и хорошо сопрягается с другими службами WPF (например, с динамической привязкой к ресурсам и стилизацией). Подробно создание объектов со свойствами, производными от DependencyProperty, обсуждается в лекции о User/Custom control’ах.
Все три способа во время выполнения демонстрируют одинаковое поведение. Вообще говоря, при создании модели данных лучше реализовать интерфейс INotifyPropertyChanged. Для использования свойств, производных от DependencyProperty, требуется, чтобы класс объекта наследовал DependencyObject, а это, в свою очередь, означает, что объект данных должен работать в STA-потоке. Применение событий для извещения об изменениях свойств приводит к разбуханию объектной модели; в общем случае этот механизм лучше оставить для свойств, которые разработчики и так привыкли отслеживать:
public class Name: INotifyPropertyChanged { ... public string First { get { return _first; } set { _first = value; NotifyChanged(“First”); } } ... public event PropertyChangedEventHandler PropertyChanged; void NotifyChanged(string property) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(property)); } } }
Раз мы применяем один и тот же паттерн ко всем трем объектам данным, то можем изменить пользовательский интерфейс и воспользоваться преимуществами новой реализации объектов. Мы заведем два неизменяемых текстовых поля (TextBlock) для отображения текущего имени и два объекта TextBox для редактирования значений. Поскольку класс Name реализует интерфейс INotifyPropertyChanged, то при изменении значений система связывания получит извещение, что приведет к обновлению объектов TextBlock:
<Window ... Text=’Object Binding’> <StackPanel> <TextBlock Text=’{Binding Path=Name.First}’ /> <TextBlock Text=’{Binding Path=Name.Last}’ /> <Grid> <Grid.RowDefinitions> <RowDefinition /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <Label Grid.Row=’0’ Grid.Column=’0’>First</Label> <TextBox Grid.Row=’0’ Grid.Column=’1’ Text=’{Binding Path=Name.First}’ /> <Label Grid.Row=’1’ Grid.Column=’0’>Last</Label> <TextBox Grid.Row=’1’ Grid.Column=’1’ Text=’{Binding Path=Name.Last}’ /> </Grid> </StackPanel> </Window>
Ввод в любое текстовое поле обновляет соответствующую область окна. Отметим, что изменение происходит только при выходе из поля. По умолчанию элемент TextBox обновляет данные только в момент потери фокуса. Чтобы изменить это поведение, нужно указать, что привязка должно обновляться при любом изменении значения свойства. Для этого служит свойство привязки UpdateSourceTrigger:
<TextBox Grid.Row=’1’ Grid.Column=’1’ Text=’{Binding Path=Name.Last, UpdateSourceTrigger=PropertyChanged}’/>
Списки сложнее простого изменения свойств. Для связывания необходимо знать, какие элементы были добавлены или удалены. С этой целью в WPF введен интерфейс INotifyCollectionChanged, в котором определено единственное событие CollectionChanged с аргументом такого типа:
public class NotifyCollectionChangedEventArgs: EventArgs { public NotifyCollectionChangedAction Action { get; } public IList NewItems { get; } public int NewStartingIndex { get; } public IList OldItems { get; } public int OldStartingIndex { get; } } public enum NotifyCollectionChangedAction { Add, Remove, Replace, Move, Reset, }
В нашем примере мы можем поддержать динамическое добавление и удаление адресов человека. Проще всего это реализуется в помощью класса ObservableCollection<T>, который наследует Collection<T> и дополнительно реализует интерфейс INotifyCollectionChanged:
public class Person: INotifyPropertyChanged { IList<Address> _addresses = new ObservableCollection<Address>(); ... }
Теперь можно модифицировать наше приложение так, чтобы все адреса отображались в списковом поле, и реализовать пользовательский интерфейс для ввода новых адресов и добавления их в список:
<!— window1.xaml —> ... <StackPanel> <ListBox ItemsSource=’{Binding Path=Addresses}’/> <Button Click=’Add’ Grid.Row=’4’>Add</Button> </StackPanel> …
// window1.xaml.cs
void Add(object sender, RoutedEventArgs e) { Address a = new Address(); a.Street1 = _street.Text; a.City = _city.Text; ((Person)DataContext).Addresses.Add(a); }
В текстовые поля можно вводить новую информацию, а при нажатии кнопки Add список адресов обновляется. Поскольку свойство Addresses реализует интерфейс INotifyCollectionChanged, система связывания получает извещение о новом адресе и корректно обновляет пользовательский интерфейс.
Привязка к объектам CLR – процедура по большей части автоматическая. Реализовав интерфейсы INotifyPropertyChanged и INotifyCollectionChanged, мы наделяем источник данных “интеллектом”.
