2016-08-18 133 views
1

我最近發現你應該在WPF中綁定密碼。我在我的登錄窗口找到了我的問題的答案,但是我很難用我的幫助程序類來解決綁定問題:PasswordHelper。該課程位於我的項目文件夾Utils之一。找不到WPF密碼綁定類型中的可附屬性

這裏是我的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}" /> 

然而,這並不能編譯,因爲它的尖叫:

「可附加屬性Bin在'PasswordHelper'類型中找不到'dPassword'「。

它也尖叫:

「名稱 'PasswordHelper' 在命名空間中不存在 'CLR的命名空間; IPdevices.Uitls;裝配= 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); 
     } 
    } 
} 

我試過清洗,重建,檢查一切,但只是不會編譯。任何見解?

回答

3

該課程位於我的一個名爲Utils的項目文件夾中。

如果這意味着該類與包含XAML的WPF應用程序在同一項目中,那麼這意味着您的xmlns可能是錯誤的。

對於當前的項目應該是:

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

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

嗯,我會...謝謝! – Dimitri

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"/> 

地方是你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; 
}