Главная » Silverlight » Определение и регистрация зависимых свойств

0

На использование зависимых свойств тратится намного больше времени, чем на их создание. Существует много причин, вынуждающих разработчика приложений Silverlight создавать собственные зависимые свойства. В первую очередь, они являются ключевым компонентом кода при создании пользовательских элементов Silverlight. Кроме того, они необходимы при добавлении в приложение анимации, связанных данных и других средств Silverlight. Без них указанные средства не будут поддержаны кодом.

Создать зависимое свойство нетрудно, однако к его синтаксису необходимо привы­кнуть. Он существенно отличается от синтаксиса обычных свойств .NET.

Первый этап создания зависимого свойства состоит в определении объекта, кото­рый его представляет. Экземпляр объекта основан на классе DependencyProperty, опре­деленном в пространстве имен System.Windows. Информация о свойстве должна быть доступной постоянно. По этой причине объект DependencyProperty необходимо опреде­лить как статическое поле в ассоциированном классе.

В качестве примера рассмотрим класс FrameworkElement, наследуемый всеми эле­ментами Silverlight. В нем определено зависимое свойство Margin, разделяемое всеми элементами. Определение свойства Margin выглядит следующим образом.

public class FrameworkElement: UIElement

{

public static readonly DependencyProperty MarginProperty;

} \

Согласно соглашению об именовании, поле, определяющее зависимое свойство, име­ет имя обычного свойства, к которому добавлен суффикс Property. Это позволяет отли­чать определения обычных и зависимых свойств. Поле определено с ключевым словом readonly, следовательно, оно может быть установлено только в статическом конструк­торе класса FrameworkElement.

Примечание. Платформа Silverlight не поддерживает систему разделения свойств, встроенную в WPF (т.е. возможность определения свойства в одном классе и применения в другом). Однако зависимые свойства Silverlight подчиняются тем же правилам наследования, что и в WPF. Например, зависимое свойство Margin, определенное в классе FrameworlElement, применимо ко всем элементам Silverlight, потому что все элементы Silverlight наследуют класс FrameworlElement.

Определение объекта DependencyProperty — лишь первый этап создания зависимо­го свойства. Чтобы его можно было применить, нужно зарегистрировать его в Silverlight. Этот этап должен быть завершен перед любым использованием свойства в коде, поэто­му его нужно выполнить в статическом конструкторе ассоциированного класса.

Платформа Silverlight гарантирует невозможность непосредственного создания экземпляра DependencyProperty, потому что класс DependencyObject не имеет от­крытого конструктора. Экземпляр DependencyObject можно создать только с помо­щью статического метода DependencyProperty.Register (). По этой же причине объ­ект DependencyProperty не может быть изменен после его создания. Все члены класса DependencyProperty доступны только для чтения. Поэтому их значения должны быть установлены посредством аргументов метода Register ().

Приведенный ниже код демонстрирует, как должен создаваться экземпляр DependencyProperty. Для инициализации свойства MarginProperty используется ста­тический конструктор класса FrameworkElement:

static FrameworkElement()

{

MarginProperty = DependencyProperty.Register("Margin", typeof(Thickness), typeof(FrameworkElement), null);

}

Метод DependencyProperty .Register () принимает следующие аргументы:

•    имя свойства (в данном примере — Margin);

•    тип данных свойства (в данном примере — структура Thickness);

•    тип, которому принадлежит свойство (в данном примере — класс FrameworkElement);

•       объект PropertyMetadata, предоставляющий дополнительную информацию; в те­кущей версии Silverlight объекты PropertyMetadata используются для хранения необязательной информации: значения свойства по умолчанию и метода обрат­ного вызова, который будет запущен при изменении свойства; если эти средства не используются, введите значение null, как в данном примере.

Примечание. Пример зависимого свойства, в котором объект PropertyMetadata используется для установки значения по умолчанию, можно найти в приложении WrapPanel.

Когда все данные предоставлены, зависимое свойство нужно зарегистрировать. Сравните: процедура обычного свойства извлекает и устанавливает значение закрыто­го поля, а в процедуре зависимого свойства Silverlight для этого используются методы GetValue () и SetValue О , определенные в базовом классе DependencyObject, как в при­веденном ниже примере.

public Thickness Margin {

get { return (Thickness)GetValue(MarginProperty) ; } set { SetValue(MarginProperty, value); }

Создавая оболочку свойства, не добавляйте в нее ничего, кроме вызова методов SetValue {) и GetValue (), как в предыдущем примере. В оболочке не должно быть ни­каких дополнительных операций, таких как проверка значений, генерация событий и т.д. Это обусловлено тем, что другие средства Silverlight могут обойти оболочку свой­ства и вызвать метод SetValue О или GetValue () непосредственно в коде. Например, синтаксический анализатор Silverlight читает разметку XAML и применяет ее для непо­средственной инициализации пользовательского интерфейса, не обращаясь к оболочке.

Теперь у вас есть полностью работоспособное зависимое свойство, которое можно установить как и обычное свойство .NET с помощью оболочки.

myElement.Margin = new Thickness(5);

Осталась лишь небольшая деталь. Зависимые свойства подчиняются строгим пра­вилам, определяющим приоритеты операций при обработке текущего значения. Даже если зависимое свойство не было установлено непосредственно, оно может уже содер­жать значение. Возможно, оно было установлено путем связывания, посредством стиля или в результате наследования в дереве элементов. Однако непосредственная установка значения переопределяет все указанные эффекты. Правила применения приоритетов рассматриваются далее в разделе.

Возможно, в будущем возникнет необходимость удалить локальное значение и пре­доставить свойству возможность вести себя так, будто оно не было установлено. По оче­видным причинам это нельзя сделать, просто установив новое значение. Вместо этого необходимо применить метод ClearValue (), наследуемый от DependencyObject.

myElement.ClearValue(FrameworkElement.MarginProperty);

Приведенный оператор вынуждает платформу Silverlight интерпретировать значе­ние таким образом, будто оно никогда не устанавливалось. Следовательно, свойство возвращается в предыдущее значение. Обычно это значение, установленное по умол­чанию, но может быть и значением, унаследованным откуда-либо или установленным посредством стиля.

Источник: Мак-Дональд, Мэтью. Silverlight 3 с примерами на С# для профессионалов. : Пер. с англ. —- М. : ООО «И.Д. Вильяме», 2010. — 656 с. : ил. — Парал. тит. англ.

По теме:

  • Комментарии