2014-01-14 2 views
2

У меня есть пользовательский элемент управления WPF с несколькими DependencyProperties.Как узнать, установлено ли у моего DependencyProperty значение NULL?

Если пользователь связывает «null» с одним из моих DependencyProperties, я хочу что-то сделать, например, изменить значение на что-то действительное.

Проблема в том, что значение по умолчанию для моего свойства равно NULL, и когда они устанавливают значение NULL для этого свойства, OnPropertyChanged не срабатывает.

Есть ли способ выполнить то, что я хочу, кроме изменения значения по умолчанию моего свойства на что-то еще, кроме NULL? Мне нужно было бы создать какое-то «макет» значение для установки по умолчанию

ответ

6

Вы можете указать CoerceValueCallback при регистрации DependencyProperty, и использовать его, чтобы заменить действительное значение всякий раз, когда вы видите базовое значение null. Значения по умолчанию не передаются в CoerceValueCallback, так что это в значительной степени ваш единственный вариант для различия между null в качестве значения по умолчанию или пользователя.

public static readonly DependencyProperty MyPropertyProperty = 
    DependencyProperty.Register(
     "MyProperty", 
     typeof(object), 
     typeof(OwnerType), 
     new PropertyMetadata(default(object), null, CoerceMyProperty)); 

private static object CoerceMyProperty(DependencyObject d, object baseValue) 
{ 
    if (baseValue == null) 
     return SomeAlternateValue; 
    return baseValue; 
} 

Если вы никогда не назначать MyProperty, вы увидите, что CoerceMyProperty никогда не вызывается, но ваш экземпляр элемента управления будет иметь значение по умолчанию (null). Кроме того, учитывая следующие две строки, CoerceMyProperty будет вызываться для первой, но не второй (который возвращается к значению по умолчанию):

this.MyProperty = null; 
this.ClearValue(MyPropertyProperty); 
0

Похоже, вы пытаетесь различать значение по умолчанию и явное значение пользователя, но оба значения одинаковы: null. Это не будет возможным, потому что событие основано на значении, и если значение не изменяется, событие не срабатывает. Похоже, вы должны посмотреть на другое значение по умолчанию, которое отличается от null. Это позволит вам провести различие между этими двумя состояниями

+0

Вы правы, что 'PropertyChangedCallback' не будет срабатывать, если значение * coerced * пользователя совпадает с значением по умолчанию, но ваше заключение ложно. Он может различать «null» как значение по умолчанию или пользователя, поскольку значение по умолчанию никогда не будет передано в «CoerceValueCallback», а значение пользователя (даже если оно соответствует текущему значению по умолчанию). –

+0

Для чего это необходимо, 'DependencyPropertyHelper.GetValueSource (obj, dp) .BaseValueSource == BaseValueSource.Local' будет определять, был ли он настроен пользователем, но до сих пор нет способа зафиксировать тот факт, что он был установлен вообще, если старые и новые значения одинаковы. Однако вы можете выполнить эту проверку на элементе управления «Инициализированное». – nmclean

+0

@nmclean Я не уверен, что вы подразумеваете под «до сих пор нет возможности зафиксировать тот факт, что он был установлен вообще, если старые и новые значения одинаковы». Вы можете наблюдать установленное действие в обратном вызове принуждения, даже если вы не предпринимаете никаких других действий. Он всегда вызывается при установке (но не очищается или когда он имеет только значение по умолчанию). Он вызывается, даже если предлагаемое значение соответствует текущему эффективному значению. –

0

Вы можете попробовать DependencyProperty.Register с валидации обратного вызова

+3

К сожалению * обратные вызовы проверки хранятся в идентификаторах свойств зависимостей, а не метаданных свойств зависимостей. Обратный вызов проверки не имеет доступа к определенному экземпляру объекта DependencyObject, на котором установлено свойство, и может влиять только на то, какие значения принимаются для свойства в целом.Если вам нужен обратный вызов, который может изменять значения свойств на основе определенного экземпляра, вы должны использовать комбинацию CoerceValueCallback и PropertyChangedCallback. * Из примечаний [здесь] (http://msdn.microsoft.com/en-us/library /system.windows.validatevaluecallback.aspx). – Clemens

Смежные вопросы