在具有WPF密码绑定的类型中找不到可附加属性

本文关键字:找不到 属性 类型 WPF 密码 绑定 | 更新日期: 2023-09-27 18:02:56

我最近发现应该在WPF中绑定密码。我找到了登录窗口问题的答案,但是我很难使用我的助手类来解决绑定问题:PasswordHelper。这门课在我的项目文件夹Utils中。

下面是我的XAML代码的一部分:

<Window x:Class="IPdevices.LoginWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:IPdevices"
        xmlns:utils="clr-namespace:IPdevices.Utils;assembly=Utils"
        mc:Ignorable="d"
         Title="IPDevices" Height="451" Width="397.5" Icon="logo3_q2J_icon.ico">

注意xmlns:utils="clr-namespace:IPdevices.Utils;assembly=Utils"

我的密码框现在是

<PasswordBox utils:PasswordHelper.BindPassword="true"  utils:PasswordHelper.BoundPassword="{Binding Path=NetworkPassword, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

然而,这不能编译,因为它在尖叫:

"在类型'PasswordHelper'中找不到可附加属性'BindPassword'。"

它也在尖叫:

"名称'PasswordHelper'在命名空间'clr-namespace; ipdevices . Utils;assembly=Utils'"

这是PasswordHelper类:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Security;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
namespace IPdevices.Utils
{
    public static class PasswordHelper
    {
        public static readonly DependencyProperty BoundPassword =
           DependencyProperty.RegisterAttached("BoundPassword", typeof(string), typeof(PasswordHelper), new PropertyMetadata(string.Empty, OnBoundPasswordChanged));
        public static readonly DependencyProperty BindPassword = DependencyProperty.RegisterAttached(
            "BindPassword", typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, OnBindPasswordChanged));
        private static readonly DependencyProperty UpdatingPassword =
            DependencyProperty.RegisterAttached("UpdatingPassword", typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false));
        private static void OnBoundPasswordChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            PasswordBox box = d as PasswordBox;
            // only handle this event when the property is attached to a PasswordBox
            // and when the BindPassword attached property has been set to true
            if (d == null || !GetBindPassword(d))
            {
                return;
            }
            // avoid recursive updating by ignoring the box's changed event
            box.PasswordChanged -= HandlePasswordChanged;
            string newPassword = (string)e.NewValue;
            if (!GetUpdatingPassword(box))
            {
                box.Password = newPassword;
            }
            box.PasswordChanged += HandlePasswordChanged;
        }
        private static void OnBindPasswordChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
        {
            // when the BindPassword attached property is set on a PasswordBox,
            // start listening to its PasswordChanged event
            PasswordBox box = dp as PasswordBox;
            if (box == null)
            {
                return;
            }
            bool wasBound = (bool)(e.OldValue);
            bool needToBind = (bool)(e.NewValue);
            if (wasBound)
            {
                box.PasswordChanged -= HandlePasswordChanged;
            }
            if (needToBind)
            {
                box.PasswordChanged += HandlePasswordChanged;
            }
        }
        private static void HandlePasswordChanged(object sender, RoutedEventArgs e)
        {
            PasswordBox box = sender as PasswordBox;
            // set a flag to indicate that we're updating the password
            SetUpdatingPassword(box, true);
            // push the new password into the BoundPassword property
            SetBoundPassword(box, box.Password);
            SetUpdatingPassword(box, false);
        }
        public static void SetBindPassword(DependencyObject dp, bool value)
        {
            dp.SetValue(BindPassword, value);
        }
        public static bool GetBindPassword(DependencyObject dp)
        {
            return (bool)dp.GetValue(BindPassword);
        }
        public static string GetBoundPassword(DependencyObject dp)
        {
            return (string)dp.GetValue(BoundPassword);
        }
        public static void SetBoundPassword(DependencyObject dp, string value)
        {
            dp.SetValue(BoundPassword, value);
        }
        private static bool GetUpdatingPassword(DependencyObject dp)
        {
            return (bool)dp.GetValue(UpdatingPassword);
        }
        private static void SetUpdatingPassword(DependencyObject dp, bool value)
        {
            dp.SetValue(UpdatingPassword, value);
        }
    }
}

我试过清理,重建,仔细检查一切,但就是不能编译。了解吗?

在具有WPF密码绑定的类型中找不到可附加属性

这个类在我的项目的一个名为Utils的文件夹中。

如果这意味着类与包含XAML的WPF应用程序在同一个项目中,那么这意味着您的xmlns可能是错误的。

对于当前项目,它应该是:

xmlns:utils="clr-namespace:IPdevices.Utils;assembly="

xmlns:utils="clr-namespace:IPdevices.Utils"

下面的代码可以更简单,更容易读

下面是Attached属性类

public static class PasswordHelper
{
    public static readonly DependencyProperty PasswordProperty =
    DependencyProperty.RegisterAttached("Password",
    typeof(string), typeof(PasswordHelper),
    new FrameworkPropertyMetadata(string.Empty, FrameworkPropertyMetadataOptions.BindsTwoWayByDefault, OnPasswordPropertyChanged));
    public static readonly DependencyProperty AttachProperty =
        DependencyProperty.RegisterAttached("Attach",
        typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, Attach));

    public static void SetAttach(DependencyObject dp, bool value)
    {
        dp.SetValue(AttachProperty, value);
    }
    public static bool GetAttach(DependencyObject dp)
    {
        return (bool)dp.GetValue(AttachProperty);
    }
    public static string GetPassword(DependencyObject dp)
    {
        return (string)dp.GetValue(PasswordProperty);
    }
    public static void SetPassword(DependencyObject dp, string value)
    {
        dp.SetValue(PasswordProperty, value);
    }

    private static void OnPasswordPropertyChanged(DependencyObject sender,
        DependencyPropertyChangedEventArgs e)
    {
        PasswordBox passwordBox = sender as PasswordBox;
        if (e.OldValue != e.NewValue)
        {
            if (!passwordBox.Password.Equals(e.NewValue))
            {
                passwordBox.Password = (string)e.NewValue;
            }
        }
    }
    private static void Attach(DependencyObject sender,
        DependencyPropertyChangedEventArgs e)
    {
        PasswordBox passwordBox = sender as PasswordBox;
        if (passwordBox == null)
            return;
        if ((bool)e.OldValue)
        {
            passwordBox.PasswordChanged -= PasswordChanged;
        }
        if ((bool)e.NewValue)
        {
            passwordBox.PasswordChanged += PasswordChanged;
        }
    }
    private static void PasswordChanged(object sender, RoutedEventArgs e)
    {
        PasswordBox passwordBox = sender as PasswordBox;
        SetPassword(passwordBox, passwordBox.Password);
    }
}

下面是XAML

 <PasswordBox local:PasswordAttached.Attach="true" local:PasswordAttached.Password="{Binding Password}"  Width="300" Margin="10" Height="26"/>

local是PasswordHelper类的命名空间

下面是视图模型

public class ViewModel : INotifyPropertyChanged
{
    private string password;
    public string Password
    {
        get
        {
            return password;
        }
        set
        {
            password = value;
            if(PropertyChanged!=null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs("Password"));
            }
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;
}