我最近发现你应该在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.Uitls; 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);
}
}
}
我已经尝试过清理,重建,仔细检查所有内容,但根本无法编译。有什么见解吗?
答案 0 :(得分:3)
这个课程位于我项目的一个名为Utils的文件夹中。
如果这意味着该类与包含XAML的WPF应用程序位于同一项目中,那么这意味着您的xmlns
可能是错误的。
对于当前项目,它应该是:
xmlns:utils="clr-namespace:IPdevices.Utils;assembly="
或
xmlns:utils="clr-namespace:IPdevices.Utils"
答案 1 :(得分:1)
代码可以更简单,更易读,如下所示
以下是附加属性类
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;
}