Работа похожа на ту, что делалась в реализации свойства Height
: тем не менее, предыдущий фрагмент кода регистрирует свойство непосредственно в теле, а не в статическом конструкторе (что хорошо). Также обратите внимание, что объект UIPropertyMetadata
используется для определения стандартного целочисленного значения (0
) вместо более сложного объекта FrameworkPropertyMetadata
. В итоге получается простейшая версия CurrentNumber
как свойства зависимости.
Добавление процедуры проверки достоверности данных
Хотя у вас есть свойство зависимости по имени CurrentNumber
(и исключение больше не генерируется), анимация пока еще не наблюдается. Следующей корректировкой будет указание функции, вызываемой для выполнения проверки достоверности данных. В данном примере предполагается, что нужно обеспечить нахождение значения свойства CurrentNumber
в диапазоне между 0 и 500.
Добавьте в метод DependencyProperty.Register()
последний аргумент типа ValidateValueCallback
, указывающий на метод по имени ValidateCurrentNumber
.
Здесь ValidateValueCallback
является делегатом, который может указывать только на методы, возвращающие тип bool
и принимающие единственный аргумент типа object
. Экземпляр object
представляет присваиваемое новое значение. Реализация ValidateCurrentNumber
должна возвращать true
, если входное значение находится в ожидаемом диапазоне, и false
в противном случае:
public static readonly DependencyProperty CurrentNumberProperty =
DependencyProperty.Register("CurrentNumber",
typeof(int),
typeof(ShowNumberControl),
new UIPropertyMetadata(100),
new ValidateValueCallback(ValidateCurrentNumber));
// Простое бизнес-правило: значение должно находиться
// в диапазоне между 0 и 500.
public static bool ValidateCurrentNumber(object value) =>
Convert.ToInt32(value) >= 0 && Convert.ToInt32(value) <= 500;
Реагирование на изменение свойства
Итак, допустимое число уже есть, но анимация по-прежнему отсутствует. Последнее изменение, которое потребуется внести — передать во втором аргументе конструктора UIPropertyMrtadata
объект PropertyChangedCallback
. Данный делегат может указывать на любой метод, принимающий DependencyObject
в первом параметре и DependencyPropertyChangeEventArgs
во втором. Модифицируйте код следующим образом:
// Обратите внимание на второй параметр конструктора UIPropertyMetadata.
public static readonly DependencyProperty CurrentNumberProperty =
DependencyProperty.Register("CurrentNumber", typeof(int),
typeof(ShowNumberControl),
new UIPropertyMetadata(100,
new PropertyChangedCallback(CurrentNumberChanged)),
new ValidateValueCallback(ValidateCurrentNumber));
Конечной целью внутри метода CurrentNumberChamged()
будет изменение свойства Content
объекта Label
на новое значение, присвоенное свойству CurrentNumber
. Однако возникает серьезная проблема:метод CurrentNumberChanged()
является статическим, т.к. он должен работать со статическим объектом DependencyProperty
. Как тогда получить доступ к объекту Label
для текущего экземпляра ShowNumberControl
? Нужная ссылка содержится в первом параметре DependencyObject
. Новое значение можно найти с применением входных аргументов события. Ниже показан необходимый код, который будет изменять свойство Content
объекта Label
:
private static void CurrentNumberChanged(DependencyObject depObj,
DependencyPropertyChangedEventArgs args)
{
// Привести DependencyObject к ShowNumberControl.
ShowNumberControl c = (ShowNumberControl)depObj;
// Получить элемент управления Label в ShowNumberControl.