100 likes | 346 Views
Классы Windows Presentation Foundation. Свойства зависимостей ( dependency properties). Система свойств WPF ( WPF property system ) - набор сервисов, которые расширяют функциональность свойств CLR.
E N D
Свойства зависимостей (dependency properties) • Система свойств WPF (WPF property system )- набор сервисов, которые расширяют функциональность свойств CLR. • Свойства, которые управляются системой свойств WPF, называются свойствами зависимостей (dependency properties). • Основной функцией системы свойств WPF является вычисление значений свойств и уведомление об изменениизначений. • Изменение значения свойства зависимостей может быть связано с различными участниками системы свойств WPF – стилями, триггерами (triggers), наследованием значений свойств, установкой локальных значений. • Свойства зависимостей (dependency properties) поддерживают • проверку корректности значений (property invalidation) • приведение типа (dependent-value coercion) • значения по умолчанию (default values) • наследование (inheritance) • привязку данных (data binding) • анимацию (animation) • оповещение об изменении значений (property change notification) • cтили (styling)
Свойства зависимостей и свойства CLR • Для свойств зависимостей из библиотек WPF определены методы {get; set}, позволяющие использовать для них обычный синтаксис CLR для свойств. • В документации WPF есть информация о том, что свойство реализовано как свойство зависимостей. • Например, свойство string Text { get; set; } классаTextBoxопределено как свойство зависимостей, а свойство string SelectedText { get; set; } классаTextBoxне является свойством зависимостей. • В WPF определены два класса для поддержкисвойств зависимостей: • DependencyProperty поддерживает регистрацию свойства зависимостей в сиcтеме свойств WPF и информацию о свойствах зависимостей; • DependencyObject используется как базовый для всех типов, в которых определяютсясвойства зависимостей.
Класс DependencyProperty • Класс поддерживает регистрацию свойства зависимостей в сиcтеме свойств WPF. • Чтобы определить пользовательское свойство зависимости, необходимо, • зарегистрировать его с помощью статического метода Register класса DependencyProperty в системе свойств WPF; • сохранить в открытом статическом поле класса (доступном только для чтения) ссылку на объект DependencyProperty, который возвращает метод Register при успешной регистрации. • При регистрации можно • определитьдля свойства обычные CLR методы доступа {get; set}(рекомендуется); • с помощью объекта типа PropertyMetadataпередать информацию о том, какие службы (привязка данных, ведение журнала, …) будут использоваться с регистрируемым свойством зависимостей.
Регистрация свойства зависимости • Регистрацию свойства зависимостей выполняет статический методRegisterкласса DependencyProperty. Метод перегружен (3). Перегруженный вариант с наибольшим числом параметров public static DependencyProperty Register( string name, Type propertyType, Type ownerType, PropertyMetadata typeMetadata, ValidateValueCallback validateValueCallback ); • При регистрации необходимо указать • имя свойства (string name); • тип свойства (Type propertyType); • тип-владелец, в котором регистрируется свойство зависимости (Type ownerType). • Дополнительно можно определить метаданные свойства зависимостей (PropertyMetadatatypeMetadata) и метод обратного вызова для пользовательской проверки корректности значений свойства . • В метаданных свойства зависимостей можно предусмотреть методы обратного вызова, которые будут вызываться при изменении значения свойства и для анализа допустимости (coerce) значения свойства.
Пример регистрации свойства зависимостей public class DoubleValueTextBox : StackPanel { public static readonlyDependencyPropertyDoubleValueProperty; static DoubleValueTextBox() { PropertyMetadata metadata = new PropertyMetadata(OnDoubleValueChanged); metadata.DefaultValue = (double) double.NaN; DoubleValueProperty = DependencyProperty.Register("DoubleValue",typeof(double), typeof(DoubleValueTextBox), metadata); } public double DoubleValue { get { return (double)this.GetValue(DoubleValueProperty); } set { this.SetValue(DoubleValueProperty, value); } } • В примере в классе DoubleValueTextBoxв статическом конструкторе зарегистрировано свойство зависимостей с именем DoubleValue. • Свойство имеет тип double, его владельцем является тип DoubleValueTextBox. • Ссылка на объект DependencyProperty находится в поле DoubleValuePropertyкласса-владельца (как имя статического поля класса принято использовать имя свойства, к которому добавлен корень Property). • Для свойства определены методы {get; set}, позволяющие использовать для него обычный синтаксис CLR для свойств (методы GetValueи SetValueопределены в классе DependencyObject). • При регистрации для свойства задано значение NaNпо умолчанию.
Класс DependencyObject • Класс является базовым для типов, использующих свойства зависимостей WPF. • Метод SetValueкласса DependencyObject задает локальное значение свойства зависимостей. Метод бросает исключение , если значение value имеет тип, который не может быть приведен к типу, указанному при регистрации свойства. public Object GetValue( DependencyProperty dp ); public void SetValue( DependencyProperty dp, Object value ); • Метод GetValueкласса DependencyObjectвозвращает текущее действующее значение свойства зависимостей. Действующее значение вычисляется системой свойств WPF с учетом всех данных, которые влияют на значение данного свойства зависимости.
Проверка корректности значения свойства • Для проверки корректности значения свойства зависимости следует определить отдельный метод с сигнатурой, отвечающей делегату ValidateValueCallback, который указывается при регистрации свойства зависимости и работает как метод обратного вызова. public delegate bool ValidateValueCallback( Object value ); • Метод выполняет пользовательскую проверку значения свойства зависимостей после обычной проверки типа, и должен возвращать значение true, если значение свойства принимается, и falseв противном случае. Метод не предполагает корректировку значения свойства – новое значение принимается или нет. • Проверку корректности значения следует выполнять в отдельном методе, а не в упаковщиках свойства { get; set}, так как • код WPF может вызвать методы SetValue или GetValueнапрямую без вызова { get; set}; • значение может зависеть от других объектов, например, свойство может унаследовать свое значение через дерево элементов или получить его в результате привязки данных.
Присоединенные (attached) свойствазависимостей • Присоединенные (вложенные) свойства зависимостей - это механизм, который дает возможность присваивать значения свойствам других классов. • Например, присоединенными свойствами зависимости являются свойства Rowи Columnвклассе Grid. • Эти свойства зарегистрированы в класеGrid как присоединенные (вложенные), вызовы методов GetValueи SetValueкласса DependencyObjectнаходятся в статических методах класса Grid: public static void SetRow( UIElement element, int value ); public static intGetRow( UIElement element ); • Пример использования в разметке: <Grid Name="grid1" ShowGridLines="True"> <Grid.RowDefinitions> <RowDefinition Height="1*" /> <RowDefinition Height="1*" /> </Grid.RowDefinitions> <Button Grid.Row="1" Margin="5,29,5,50" Name="button1“ Click="button1_Click"> Add </Button> </Grid> • Пример использования в коде: Button btn = new Button(); btn.Content = "Set"; Grid.SetRow(btn, 1); Grid.SetColumn(btn, 1); grid_1.Children.Add(btn);
Регистрация присоединенного свойствазависимостей • Для регистрации присоединенного свойства зависимостей используется одна из перегрузок методаRegisterAttachedкласса DependencyProperty. Перегруженный вариант с наибольшим числом параметров public static DependencyProperty RegisterAttached( string name, Type propertyType, Type ownerType, PropertyMetadata defaultMetadata, ValidateValueCallback validateValueCallback ); • Параметры метода имеют такой же смысл как в методе Register(). • Регистрация присоединенного свойства отличается от регистрации свойства зависимости тем, что вызовы методов GetValueи SetValueупаковываются не в методы {get; set }, а в статические методы с именами SetИмяСвойства() и GetИмяСвойства().