Как связать с прикрепленным свойством в XAML, WPF - PullRequest
4 голосов
/ 25 февраля 2011

Я хотел бы привязать свойство User.Password к PasswordBox (TwoWay). Поскольку PasswordBox.Password не является привязываемым, я сделал AttachedProperties, чтобы исправить это (один для активации привязки, а другой для хранения действительного пароля). Проблема в том, что они не будут связываться (GetBindingExpression возвращает ноль).

Также:

  • AttachedProperties работают. Пароль и PasswordValue (прикрепленная опора) устанавливаются правильно, если я ввожу в PasswordBox, но User.Password остается пустым.
  • Привязка AttachedProperty также работает, но только наоборот: если я связываю PasswordValue с TextBlock (TextBlock.Text является целью, helper: PasswordValue является источником), он работает. Только я не могу использовать это, потому что свойства User не являются объектами зависимости.
  • User.Password является привязываемым (пользователь реализует INotifyPropertyChanged), и мне удалось привязать User.Username к TextBox.Text и (Имя пользователя и Пароль - аналогичные строковые свойства)

Вот прикрепленные свойства:

public static bool GetTurnOnBinding(DependencyObject obj)
        {
            return (bool)obj.GetValue(TurnOnBindingProperty);
        }

        public static void SetTurnOnBinding(DependencyObject obj, bool value)
        {
            obj.SetValue(TurnOnBindingProperty, value);
        }

        // Using a DependencyProperty as the backing store for TurnOnBinding. This enables animation, styling, binding, etc...
        public static readonly DependencyProperty TurnOnBindingProperty =
            DependencyProperty.RegisterAttached(
            "TurnOnBinding",
            typeof(bool),
            typeof(PasswordHelper),
            new UIPropertyMetadata(false, (d, e) =>
            {
                var pb = d as PasswordBox;
                SetPasswordValue(pb, pb.Password);
                pb.PasswordChanged += (s, x) => SetPasswordValue(pb, pb.Password);
            }));

        public static string GetPasswordValue(DependencyObject obj)
        {
            return (string)obj.GetValue(PasswordValueProperty);
        }

        public static void SetPasswordValue(DependencyObject obj, string value)
        {
            obj.SetValue(PasswordValueProperty, value);
        }

        // Using a DependencyProperty as the backing store for PasswordValue.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty PasswordValueProperty =
            DependencyProperty.RegisterAttached(
            "PasswordValue",
            typeof(string),
            typeof(PasswordHelper), new UIPropertyMetadata(null, (d, e) =>
            {
                PasswordBox p = d as PasswordBox;
                string s = e.NewValue as string;

                if (p.Password != s) p.Password = s;
            }));

И часть XAML с привязкой:

<PasswordBox x:Name="passBox" 
    root:PasswordHelper.TurnOnBinding="True" 
    root:PasswordHelper.PasswordValue="{Binding Text, 
        ElementName=passSupport, Mode=TwoWay}"/>

Ответы [ 2 ]

2 голосов
/ 26 февраля 2011

Извините, я не могу сказать, что не так с вашим кодом (ИМХО, он должен работать), но, поскольку у меня была похожая проблема в Silverlight, и дизайнеру не очень нравится привязка к присоединенным свойствам и из них, я обнаружили, что они не стоят хлопот.
Мой текущий предпочтительный метод расширения поведения элементов управления - использование базового класса System.Windows.Interactivity.Behavior (см. здесь и здесь ), а затем присоединение моего поведения к элементам управления.

Таким образом, вам понадобится class PasswordBehavior : Behavior<PasswordBox>, который переопределяет OnAttached() и подписывается на событие PasswordBox PasswordChanged, и имеет привязываемый объект DependencyProperty с именем PasswordValue. В обработчике событий измените значение dp, а в обратном вызове dp измените значение пароля элемента управления.

0 голосов
/ 26 февраля 2011

Оформить PasswordBoxAssistant . Просто измените свойства BoundPassword => BoundPasswordProperty, BindPassword => BindPasswordProperty, UpdatingPassword => UpdatingPasswordProperty, чтобы избежать предупреждений в представлении XAML.

...