Чтение онлайн

на главную

Жанры

Язык программирования C#9 и платформа .NET5
Шрифт:

Исследование существующего свойства зависимости

Прежде чем вы научитесь создавать специальные свойства зависимости, давайте рассмотрим внутреннюю реализацию свойства

Height
класса
FrameworkElement
. Ниже приведен соответствующий код (с комментариями):

// FrameworkElement "является" DependencyObject.

public class FrameworkElement : UIElement, IFrameworkInputElement,

IInputElement, ISupportInitialize, IHaveResources, IQueryAmbient

{

...

//
Статическое поле только для чтения типа DependencyProperty.

public static readonly DependencyProperty HeightProperty;

// Поле DependencyProperty часто регистрируется

// в статическом конструкторе класса.

static FrameworkElement

{

...

HeightProperty = DependencyProperty.Register(

"Height",

typeof(double),

typeof(FrameworkElement),

new FrameworkPropertyMetadata((double) 1.0 / (double) 0.0,

FrameworkPropertyMetadataOptions.AffectsMeasure,

new PropertyChangedCallback(FrameworkElement.OnTransformDirty)),

new ValidateValueCallback(FrameworkElement.IsWidthHeightValid));

}

// Оболочка CLR, реализованная с использованием

// унаследованных методов GetValue/SetValue.

public double Height

{

get { return (double) base.GetValue(HeightProperty); }

set { base.SetValue(HeightProperty, value); }

}

}

Как видите, по сравнению с обычными свойствами CLR свойства зависимости требуют немалого объема дополнительного кода. В реальности зависимость может оказаться даже еще более сложной, чем показано здесь (к счастью, многие реализации проще свойства

Height
).

В первую очередь вспомните, что если в классе необходимо определить свойство зависимости, то он должен иметь в своей цепочке наследования

DependencyObject
, т.к. именно этот класс определяет методы
GetValue
и
SetValue
, применяемые в оболочке CLR. Из-за того, что класс
FrameworkElement
"является"
DependencyObject
, указанное требование удовлетворено.

Далее вспомните, что сущность, где действительно хранится значение свойства (значение

double
в случае
Height
), представляется как открытое, статическое, допускающее только чтение поле типа
DependencyProperty
. По соглашению имя этого свойства должно всегда формироваться из имени связанной оболочки CLR с добавлением суффикса
Property
:

public static readonly DependencyProperty HeightProperty;

Учитывая,

что свойства зависимости объявляются как статические поля, они обычно создаются (и регистрируются) внутри статического конструктора класса. Объект
DependencyProperty
создается посредством вызова статического метода
DependencyProperty.Register
. Данный метод имеет множество перегруженных версий, но в случае свойства
Height
он вызывается следующим образом:

HeightProperty = DependencyProperty.Register(

"Height",

typeof(double),

typeof(FrameworkElement),

new FrameworkPropertyMetadata((double)0.0,

FrameworkPropertyMetadataOptions.AffectsMeasure,

new PropertyChangedCallback(FrameworkElement.OnTransformDirty)),

new ValidateValueCallback(FrameworkElement.IsWidthHeightValid));

Первым аргументом, передаваемым методу

DependencyProperty.Register
, является имя обычного свойства CLR класса (
Height
), а второй аргумент содержит информацию о типе данных, который его инкапсулирует (
double
). Третий аргумент указывает информацию о типе класса, которому принадлежит свойство (
FrameworkElement
). Хотя такие сведения могут показаться избыточными (в конце концов, поле
HeightProperty
уже определено внутри класса
FrameworkElement
), это довольно продуманный аспект WPF, поскольку он позволяет одному классу регистрировать свойства в другом классе (даже если его определение было запечатано).

Четвертый аргумент, передаваемый методу

DependencyProperty.Register
в рассмотренном примере, представляет собой то, что действительно делает свойства зависимости уникальными. Здесь передается объект
FrameworkPropertyMetadata
, который описывает разнообразные детали относительно того, как инфраструктура WPF должна обрабатывать данное свойство в плане уведомлений с помощью обратных вызовов (если свойству необходимо извещать других, когда его значение изменяется). Кроме того, объект
FrameworkPropertyMetadata
указывает различные параметры (представленные перечислением
FrameworkPropertyMetadataOptions
), которые управляют тем, на что свойство воздействует (работает ли оно с привязкой данных, может ли наследоваться и т.д.). В данном случае аргументы конструктора
FrameworkPropertyMetadata
можно описать так:

new FrameworkPropertyMetadata(

// Стандартное значение свойства.

(double)0.0,

// Параметры метаданных.

FrameworkPropertyMetadataOptions.AffectsMeasure,

// Делегат, который указывает на метод,

// вызываемый при изменении свойства.

new PropertyChangedCallback(FrameworkElement.OnTransformDirty)

)

Поделиться:
Популярные книги

Меняя маски

Метельский Николай Александрович
1. Унесенный ветром
Фантастика:
боевая фантастика
попаданцы
9.22
рейтинг книги
Меняя маски

Курсант: назад в СССР 9

Дамиров Рафаэль
9. Курсант
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Курсант: назад в СССР 9

Лорд Системы 13

Токсик Саша
13. Лорд Системы
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Лорд Системы 13

Кротовский, может, хватит?

Парсиев Дмитрий
3. РОС: Изнанка Империи
Фантастика:
попаданцы
альтернативная история
аниме
7.50
рейтинг книги
Кротовский, может, хватит?

"Дальние горизонты. Дух". Компиляция. Книги 1-25

Усманов Хайдарали
Собрание сочинений
Фантастика:
фэнтези
боевая фантастика
попаданцы
5.00
рейтинг книги
Дальние горизонты. Дух. Компиляция. Книги 1-25

Месть Пламенных

Дмитриева Ольга
6. Пламенная
Фантастика:
фэнтези
6.00
рейтинг книги
Месть Пламенных

Как я строил магическую империю 6

Зубов Константин
6. Как я строил магическую империю
Фантастика:
попаданцы
аниме
фантастика: прочее
фэнтези
5.00
рейтинг книги
Как я строил магическую империю 6

Идеальный мир для Лекаря 24

Сапфир Олег
24. Лекарь
Фантастика:
городское фэнтези
попаданцы
5.00
рейтинг книги
Идеальный мир для Лекаря 24

Внешняя Зона

Жгулёв Пётр Николаевич
8. Real-Rpg
Фантастика:
фэнтези
попаданцы
рпг
5.00
рейтинг книги
Внешняя Зона

Архил…? Книга 3

Кожевников Павел
3. Архил...?
Фантастика:
фэнтези
попаданцы
альтернативная история
7.00
рейтинг книги
Архил…? Книга 3

Идеальный мир для Лекаря 18

Сапфир Олег
18. Лекарь
Фантастика:
юмористическое фэнтези
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 18

Барон ненавидит правила

Ренгач Евгений
8. Закон сильного
Фантастика:
попаданцы
аниме
фэнтези
5.00
рейтинг книги
Барон ненавидит правила

Идеальный мир для Лекаря 14

Сапфир Олег
14. Лекарь
Фантастика:
юмористическое фэнтези
попаданцы
аниме
5.00
рейтинг книги
Идеальный мир для Лекаря 14

Дворянская кровь

Седой Василий
1. Дворянская кровь
Фантастика:
попаданцы
альтернативная история
7.00
рейтинг книги
Дворянская кровь