2009-05-20 47 views
10

Tôi chỉ mới bắt đầu với M-V-VM và WPF và gặp sự cố khi hiểu một số vấn đề ràng buộc.Ràng buộc hộp mật khẩu

Tôi có trang đăng nhập có ComboBoxPasswordBox. Các ComboBox trông như thế này:

<ComboBox Name="comboBox1" SelectedItem="{Binding Path=Username}"> 

này chỉ hoạt động tốt - giá trị của tôi được cập nhật mọi sự thay đổi trên SelectedItemComboBox!

Trong ViewModel của tôi Tôi có một ICommand trong đó sử dụng phương pháp này để xác định xem các nút Login đang hoạt động:

public bool CanLogin() 
{ 
    return !string.IsNullOrEmpty(Username) && !string.IsNullOrEmpty(Password); 
} 

Vì vậy, vấn đề của tôi là tôi không có PasswordBox ràng buộc với tài sản Password trên ViewModel - vì vậy tôi không có cách nào để nói khi nào nó được cập nhật.

Vậy làm cách nào để nhận giá trị của PasswordBox cho ViewModel của tôi? Mọi thứ tôi đọc chỉ nói không ràng buộc một số PasswordBox vì lý do bảo mật. Tôi chỉ đơn giản là sẽ tắt giới hạn mật khẩu trên CanLogin() nhưng tôi cần giá trị để chuyển sang một AccountService.

+0

Nếu bạn ràng buộc mật khẩu dưới dạng chuỗi (và không phải SecureString), bạn đang hiển thị mật khẩu trong bộ nhớ của quá trình. Cả hai giải pháp này đều thỏa hiệp an ninh – Rubinsh

Trả lời

27

Thú vị.

xem bài đăng trên blog này và xem liệu nó có đang giúp bạn hay không. http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html

Rõ ràng liên kết là chết ngay bây giờ để ở đây là giải pháp ban đầu (tìm thấy here):

Bạn có thể sử dụng tài sản gắn liền để tạo ra một helper như thế này:

 
public static class PasswordHelper 
{ 
    public static readonly DependencyProperty PasswordProperty = 
     DependencyProperty.RegisterAttached("Password", 
     typeof(string), typeof(PasswordHelper), 
     new FrameworkPropertyMetadata(string.Empty, OnPasswordPropertyChanged)); 

    public static readonly DependencyProperty AttachProperty = 
     DependencyProperty.RegisterAttached("Attach", 
     typeof(bool), typeof(PasswordHelper), new PropertyMetadata(false, Attach)); 

    private static readonly DependencyProperty IsUpdatingProperty = 
     DependencyProperty.RegisterAttached("IsUpdating", typeof(bool), 
     typeof(PasswordHelper)); 


    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 bool GetIsUpdating(DependencyObject dp) 
    { 
     return (bool)dp.GetValue(IsUpdatingProperty); 
    } 

    private static void SetIsUpdating(DependencyObject dp, bool value) 
    { 
     dp.SetValue(IsUpdatingProperty, value); 
    } 

    private static void OnPasswordPropertyChanged(DependencyObject sender, 
     DependencyPropertyChangedEventArgs e) 
    { 
     PasswordBox passwordBox = sender as PasswordBox; 
     passwordBox.PasswordChanged -= PasswordChanged; 

     if (!(bool)GetIsUpdating(passwordBox)) 
     { 
      passwordBox.Password = (string)e.NewValue; 
     } 
     passwordBox.PasswordChanged += PasswordChanged; 
    } 

    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; 
     SetIsUpdating(passwordBox, true); 
     SetPassword(passwordBox, passwordBox.Password); 
     SetIsUpdating(passwordBox, false); 
    } 
} 

Sử dụng nó:

<PasswordBox w:PasswordHelper.Attach="True" 
      w:PasswordHelper.Password="{Binding Text, ElementName=plain, Mode=TwoWay}" 
      Width="100"/> 
+0

Tôi biết đây là câu trả lời và công việc thực sự cũ, nhưng có ai chú ý đến mã này không? Có lẽ tôi nên đăng một phiên bản ít phức tạp của nó? –

+1

Đoạn mã trên không hoạt động (PasswordHelper), sử dụng phương thức trong liên kết thay thế (PasswordBoxAssistant). http://blog.functionalfun.net/2008/06/wpf-passwordbox-and-data-binding.html – morph85

8

Tôi đã đăng GIST here là hộp mật khẩu có thể kết nối.

+1

Giải pháp tốt. Bất kỳ mẹo nào về cách dễ dàng nâng cao các thuộc tính (ví dụ: Foreground, Background) của PasswordBox được nhúng để chúng có thể được truy cập trong XAML? –

Các vấn đề liên quan