2016-08-18 4 views
1

Ich habe kürzlich entdeckt, dass Sie Passwörter in WPF binden sollten. Ich habe meine Antwort auf mein Problem für mein Anmeldefenster gefunden, aber es fällt mir schwer, meine Hilfsklasse zu verwenden, um das Bindeproblem zu lösen: PasswordHelper. Diese Klasse befindet sich in einem Ordner meines Projekts namens Utils.Attachable-Eigenschaft nicht in Typ mit WPF Password Binding gefunden

Hier ist ein Teil meiner XAML-Code:

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

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

Mein Passwort-Box jetzt

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

Allerdings ist dies nicht kompilieren, weil es schreit:

"Die anfügbare Eigenschaft" Bin dPassword 'wurde im Typ' PasswordHelper 'nicht gefunden. "

Es ist auch schreien:

"Der Name 'PasswordHelper' existiert nicht im Namensraum 'clr-Namespace; IPdevices.Uitls, Montag = Utils'"

Und hier ist die PasswordHelper Klasse :

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); 
     } 
    } 
} 

Ich habe versucht, zu reinigen, Wiederaufbau, alles doppelt überprüfen, aber einfach nicht kompilieren. Irgendeine Einsicht?

Antwort

3

Diese Klasse befindet sich in einem Ordner meines Projekts namens Utils.

Wenn das bedeutet, dass die Klasse im selben Projekt wie die WPF-Anwendung, die die XAML enthält, dann das bedeutet, dass Ihre xmlns wahrscheinlich falsch ist.

Für das aktuelle Projekt soll es sein:

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

oder

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

Nun, ich werde sein ... Danke! – Dimitri

1

Der Code wenig mehr sein kann einfacher und lesbar wie unter

Im Folgenden wird die angebaute Festigkeitsklasse

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); 
    } 
} 

Unten ist die XAML

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

lokal ist Namespace Ihrer PasswordHelper Klasse

Unterhalb der Ansicht Modell ist

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; 
}