如何在XAML、WPF中绑定附加属性

5
我想将User.Password属性绑定到PasswordBox(双向)。由于PasswordBox.Password不可绑定,因此我创建了一个附加属性来解决这个问题(一个用于激活绑定,一个用于保存实际密码)。但是它们无法绑定(GetBindingExpression返回null)。
另外:
- 附加属性是有效的。如果我在PasswordBox中输入,则Password和PasswordValue(附加属性)会正确设置,但是User.Password仍为空。 - 绑定附加属性也有效,但只能反过来使用:如果我将PasswordValue绑定到TextBlock(TextBlock.Text是目标,helper:PasswordValue是源),则它可以工作。但我不能使用这种方法,因为User的属性不是依赖对象。 - User.Password是可绑定的(User实现了INotifyPropertyChanged),我设法将User.Username绑定到TextBox.Text,其中Username和Password是类似的字符串属性。
以下是附加属性:
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
抱歉,我不能确定您的代码出了什么问题(依我之见它应该可以工作),但是由于我在Silverlight中遇到了类似的问题,并且设计师并不喜欢绑定和使用附加属性,所以我发现它们不值得麻烦。
我目前首选的扩展控件行为的方法是使用System.Windows.Interactivity.Behavior基类(请参阅这里这里),然后将我的行为附加到控件上。

因此,您需要一个class PasswordBehavior : Behavior<PasswordBox>,它重写OnAttached(),并订阅passwordBox的PasswordChanged事件,并具有一个可绑定的DependencyProperty称为PasswordValue。在事件处理程序中更改dp的值,在dp的回调中更改控件的密码值。


0

看看PasswordBoxAssistant。只需更改属性BoundPassword => BoundPasswordProperty,BindPassword => BindPasswordProperty,UpdatingPassword => UpdatingPasswordProperty即可避免在XAML视图中出现警告。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接