Строка RegisterAttached PropertyName, из-за которой AttachedProperty не срабатывает

Я столкнулся со странной проблемой с прикрепленными свойствами: когда я присваиваю имя свойства в вызове RegisterAttached и правильно называю имя прикрепленного свойства (скажем, TranslateProperty и «Перевести»), код для реализации прикрепленного свойства не работает. огонь. Просто не звонят. Если я изменю имя строки на любое другое, кроме Translate (скажем, «Translate_»), код будет вызываться просто отлично.

Вот реализация:

открытый класс TranslateExtension: DependencyObject {

public static readonly DependencyProperty TranslateProperty =
    DependencyProperty.RegisterAttached("Translate_",
                                        typeof(bool),
                                        typeof(TranslateExtension),
                                        new FrameworkPropertyMetadata(false, FrameworkPropertyMetadataOptions.AffectsRender));

public static void SetTranslate(UIElement element, bool value)
    {
        AssignKeys(element);
        element.SetValue(TranslateProperty, value);
    }
    public static bool GetTranslate(UIElement element)
    {
        return (bool)element.GetValue(TranslateProperty);
    }

    public bool Translate
    {
        set { base.SetValue( TranslateProperty,  value); }
    }
   ...
}

Вышеупомянутое на самом деле работает, потому что свойство в строке — Translate_. Если я изменю строковое значение на «Перевести», это не удастся.

У меня есть 2 других прикрепленных свойства в том же классе, и они демонстрируют точно такое же поведение - то же имя, что и у AttachedProperty, и они не вызываются. Назовите это как-нибудь иначе, и оно сработает.

Я не уверен, что здесь происходит. Мой код на самом деле работает с недопустимыми именами, но я не понимаю, почему, и, что более важно, я не уверен, вызывает ли это неправильное имя какие-либо побочные эффекты.

Может ли кто-нибудь увидеть, не упускаю ли я из виду что-то болезненно очевидное? Я просмотрел несколько примеров в статьях AttachedProperties, и я не вижу этих реализаций, использующих специальные имена — они всегда называют строковое свойство так же, как прикрепленные свойства.


person Rick Strahl    schedule 17.06.2009    source источник


Ответы (1)


Вы не должны помещать дополнительный код в свой SetTranslate, так как он не будет вызываться. Из MSDN здесь:

Последствия для пользовательских свойств зависимостей

Поскольку текущая реализация WPF поведения процессора XAML для настройки свойства полностью обходит оболочки, не следует добавлять какую-либо дополнительную логику в определения набора оболочек для пользовательского свойства зависимостей. Если вы поместите такую ​​логику в определение набора, она не будет выполняться, когда свойство установлено в XAML, а не в коде.

Точно так же другие аспекты процессора XAML, которые получают значения свойств из обработки XAML, также используют GetValue, а не используют оболочку. Поэтому вам также следует избегать любой дополнительной реализации в определении get, кроме вызова GetValue.

Вместо этого добавьте PropertyChangedCallback в ваш FrameworkPropertyMetadata.

person micahtan    schedule 17.06.2009
comment
Ага, это точно! Добавление PropertyChangedCallback() в новый конструктор FrameworkMetaData() помогло. Тем не менее мне интересно, почему наличие недопустимого имени (например, Translate_) вызовет вызов метода SetTranslate. Это действительно странное поведение. - person Rick Strahl; 18.06.2009