
- •«Комп’ютерні технології та програмування»
- •Оглавление
- •Лабораторная работа 1 Знакомство с wpf
- •Теоретические сведения
- •1. Знакомство с редактором xaml
- •2.Создание приложения wpf
- •3) Создание обработчиков событий
- •Задание к лабораторной работе
- •Варианты индивидуальных заданий
- •Контрольные вопросы
- •Лабораторная работа 2 Подробное введение в разработку приложений wpf
- •Теоретические сведения
- •1. Ознакомление с управлением проектами wpf в msVisualStudio
- •2. Создание тестового приложения wpf
- •Задание к лабораторной работе
- •Варианты индивидуальных заданий
- •Контрольные вопросы
- •Лабораторная работа 3 Макет программы и основные элементы управления
- •Теоретически сведения
- •1. Макет в wpf
- •2. Новые возможности wpf
- •3. Элемент управления Canvas
- •4. Элементуправления StackPanel
- •5. Элементуправления WrapPanel
- •6. Элемент управления DockPanel
- •7. Элемент Grid
- •Задание к лабораторной работе
- •Варианты индивидуальных заданий
- •Контрольные вопросы
- •Лабораторная работа 4
- •Xaml и код, расширения разметки и ресурсы
- •Теоретически сведения
- •2. Ссылки на ресурсы в wpf
- •Задание к лабораторной работе
- •Варианты индивидуальных заданий
- •Контрольные вопросы
- •Лабораторная работа 6 Свойства зависимости
- •Теоретически сведения
- •1. Особенности свойств clr
- •2. Наследование значений свойств зависимости
- •3. Присоединенные свойства
- •4. Метаданныесвойствзависимости
- •5. Проверка допустимости значения
- •Задание к лабораторной работе
- •Варианты индивидуальных заданий
- •Контрольные вопросы
- •Лабораторная работа 7 Привязка данных
- •Теоретически сведения
- •1. Концепция привязки данных
- •2. Свойство DataContext
- •3. Основные понятия привязки данных
- •4. Синтаксис привязки данных
- •5. Привязка к элементам интерфейса пользователя
- •6. Привязка к xml
- •7. Привязка к коллекции
- •8. Преобразователи значений привязки данных
- •9. Проверкапривязкиданных
- •Задание к лабораторной работе
- •Варианты индивидуальных заданий
- •Контрольные вопросы
4. Метаданныесвойствзависимости
Класс FrameworkPropertyMetadata наследуетсяоткласса PropertyMetadata, идлябольшинствацелейразработкиприложенийуровняплатформы WPF вкачествеметаданныхсвойствиспользуетсятип FrameworkPropertyMetadata, анебазовыетипыметаданных PropertyMetadata или UIPropertyMetadata. Это касается сценариев как с имеющимися, так и с пользовательскими свойствами зависимости.
При каждом определении регистрации и добавления или присоединения свойства зависимости необходимо предоставить экземпляр класса FrameworkPropertyMetadata. Так мы информируем систему свойств WPF о необходимости особым образом обращаться со свойством зависимости, использующим этот экземпляр FrameworkPropertyMetadata. (рис. 6.10)
Рис. 6.10 - …
С помощью класса FrameworkPropertyMetadata можно предоставить системе свойств следующую информацию:
значения по умолчанию;
одноиззначений FrameworkPropertyMetadataOptions, например AffectsMeasure/AffectsArrange/AffectsRender/Inherits ит. д.;
делегаты обратного вызова измененных свойств;
приведенные значения;
отмена поддержки анимации для свойства;
предоставление одного из событий UpdateSourceTrigger, например PropertyChanged, LostFocus, Explicit и т. д.
Всего один экземпляр FrameworkPropertyMetadata дает жесткий контроль над множеством метаданных свойства зависимости.
Проверка и обратные вызовы свойства зависимости и приведенные значения. У вас, наверное, могло сложиться мнение, что свойства зависимости довольно сложные и мощные. Но не следует забывать еще о нескольких принципах. Вот они:
обратные вызовы для тех случаев, когда изменяется свойство зависимости;
приведенные значения для изменения неприемлемого значения свойства зависимости;
проверка допустимости значения.
Использование делегатов при первой регистрации свойства зависимости решает большинство из перечисленных задач. В состав прилагаемого решения (вверху статьи) входит проект Callback_Validation_DPs, демонстрирующий эти принципы. По сути, есть класс Gauge, наследуемый от класса Control, с тремя свойствами зависимости:
CurrentReading
MinReading
MaxReading
Каждое из них предназначено для проверки допустимости. Значение CurrentReading сравнивается со значениями свойств зависимости MinReading и MaxReading и при необходимости приводится. Рассмотрим пример применения этих свойств.
Рис. 6.11 - Демонстрационное приложение
При работе демонстрационное приложение выглядит так (рис. 6.11).
Обратные вызовы и приведенные значения для случаев, когда изменяется свойство зависимости. Свойствозависимости CurrentReading объявляетсятак.
public static readonly DependencyProperty CurrentReadingProperty =
DependencyProperty.Register(
"CurrentReading",
typeof(double),
typeof(Gauge),
new FrameworkPropertyMetadata(
Double.NaN,
FrameworkPropertyMetadataOptions.None,
new PropertyChangedCallback(OnCurrentReadingChanged),
new CoerceValueCallback(CoerceCurrentReading)
),
new ValidateValueCallback(IsValidReading)
);
Объект объявляется CoerceValueCallbackс делегатом, указывающим на метод CoerceCurrentReading, при объявлении которого свойство CurrentReadingсравнивается со свойствами зависимости Min/Maxи приводится при необходимости. Также обратите внимание на объявление объекта PropertyChangedCallbackс делегатом, указывающим на метод OnCurrentReadingChanged, который, в свою очередь, обеспечивает при необходимости приведение свойств зависимости Min/Max. В основном это делается для того, чтобы свойство зависимости Minбыло меньше Max и аналогично для свойства зависимости Max. В моем примере свойства зависимости Min/Maxна самом деле не изменяются, но я хотел показать, как это делается на случай, если это вам понадобится.
private static void OnCurrentReadingChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
d.CoerceValue(MinReadingProperty); //вызовделегата CoerceValueCallback ("CoerceMinReading")
d.CoerceValue(MaxReadingProperty); //вызовделегата CoerceValueCallback ("CoerceMaxReading")
}
...
...
...
///
/// Приведение значения Coerce CurrentReading, если оно выходит за допустимые пределы
///
private static object CoerceCurrentReading(DependencyObject d, object value)
{
Gauge g = (Gauge)d;
double current = (double)value;
if (current < g.MinReading) current = g.MinReading;
if (current > g.MaxReading) current = g.MaxReading;
return current;
}
Здесь происходит приведение значения свойства зависимости CurrentReading в диапазоне от MinReadingи MaxReading, при этом выполняется условие Min < Max и Max > Min. Так что мы никогда не выйдем за привязанные значения для любого из этих трех свойств зависимости.