Для WPF AttachedProperty можете ли вы проверить значение на основе типа, к которому вы присоединяетесь?

Короче говоря, мы создаем присоединенное свойство, которое будет применяться только к FrameworkElement или одному из его подклассов. Мы хотим заблокировать набор, если он применяется к чему-то, чего нет.

Теперь мы не можем использовать ValidateValueCallback, поскольку ему передается только значение свойства, а не то, к чему вы прикрепляете свойство.

Точно так же мы не можем использовать PropertyChangedCallback, потому что значение уже установлено в этой точке, а NewValue доступно только для чтения, и по какой-то причине мы не можем заставить ClearValue «застрять» внутри.

Итак... в любом случае делать то, что мы хотим?


person Mark A. Donohoe    schedule 22.09.2011    source источник


Ответы (2)


Да! Это было не ValidateValueCallback, это было CoerceValueCallback, так как это дает вам объект! Сделано и сделано!

ОБНОВЛЕНИЕ

Сотрите это. На самом деле это не на 100% правильно, так как я забыл о приоритете значений.

MSDN: приоритет значений свойств зависимостей

Другими словами, он по-прежнему фактически установлен, но просто снова принудительно возвращается к значению по умолчанию, что в нашем случае означает «не установлено». Черт.

Я начинаю думать, что единственный реальный способ сделать это здесь — просто бросить InvalidOperationExcepton в PropertyChangedCallback, но я не уверен, что даже это сработает на 100%, поскольку я считаю, что значение уже установлено, когда вы внутри Это.

Я вернусь к вам с окончательным. Продолжайте получать ответы!

person Mark A. Donohoe    schedule 22.09.2011

Да, это возможно, но вы делаете это в своих методах Get и Set, контролируя тип первого параметра. Если вы хотите, чтобы только FrameworkElements могли получить или установить значение, вы должны использовать только элементы фреймворка в методах get и set. Это не позволит элементам, не относящимся к платформе, установить значение через XAML.

public static readonly DependencyProperty MyPropertyProperty = DependencyProperty.RegisterAttached(...)

public static bool GetMyProperty(FrameworkElement e)
{
   return (bool)e.GetValue(MyPropertyProperty);
}
public static void SetMyProperty(FrameworkElement e, bool value)
{
   e.SetValue(MyPropertyProperty, value);

}

person cordialgerm    schedule 22.09.2011
comment
Это не работает. Что ж, это частично так, потому что он заблокирует его установку в XAML (он вызовет исключение во время выполнения), вы все равно можете установить его с помощью кода программной части, поскольку вы можете обойти геттер и сеттер CLR. Вот почему вы никогда не должны вкладывать в эти методы какую-либо логику — нет никакой гарантии, что они будут использоваться. Они предназначены только для удобства при вызове непосредственно из кода, но их можно легко обойти, просто вызвав e.SetValue(MyPropertyProperty, value) напрямую. - person Mark A. Donohoe; 09.05.2015