从XBox中定义的ListBoxItems的ListBox中的PasswordBox获取密码

时间:2013-12-02 07:10:28

标签: c# .net wpf xaml listbox

我有一个WPF ListBox,每个ListBoxItem有多个UIElements。其中一个UIElementsPasswordBox。这些UIElementsXaml ControlTemplate中定义。

我需要做的是在后面的代码中从Password获取PasswordBox字符串。但我无法绑定Password的{​​{1}}属性,它不是动态属性,因为PasswordBox不应该长时间存储在内存中。

现在我想到的解决方案是让Password的{​​{1}}代码落后并从那里获得UIElements

但我无法弄清楚如何从ListBox中获取代码中的ListBoxItem

1 个答案:

答案 0 :(得分:3)

密码框的密码属性不是依赖属性,因此您无法绑定此属性。

您可以通过以下任一方式从密码箱控件获取密码。

  1. 将密码框控件作为参数传递给附带项目的命令。

    XAML

    <Window x:Class="WpfApplication4.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
    <StackPanel>
        <PasswordBox Name="txtPassword" VerticalAlignment="Top" Width="120" />
        <Button Content="Ok" Command="{Binding Path=OkCommand}" CommandParameter="{Binding ElementName=txtPassword}"/>
    </StackPanel>
    

  2. 代码

    public class MyViewModel : INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;
    
            [NotifyPropertyChangedInvocator]
            protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
            {
                PropertyChangedEventHandler handler = PropertyChanged;
                if (handler != null) handler(this, new PropertyChangedEventArgs(propertyName));
            }
    
            public ICommand OkCommand { get; private set; }
    
            public MyViewModel()
            {
                OkCommand = new GeneralCommand<object>(ExecuteOkCommand, param => CanExecuteCommand());
            }
    
            private void ExecuteOkCommand(object parameter)
            {
                var passwordBox = parameter as PasswordBox;
                var password = passwordBox.Password;
            }
    
            private bool CanExecuteCommand()
            {
                return true;
            }
        }
    

    这略微违反了MVVM模式,因为现在viewmodel知道视图是如何实现的。

    1. 使用attach属性绑定密码。
    2. <强> XAML

      <StackPanel>
          <PasswordBox w:PasswordHelper.Attach="True" 
               w:PasswordHelper.Password="{Binding Text, ElementName=plain, Mode=TwoWay}" 
                       Width="130"/>
          <TextBlock Padding="10,0" x:Name="plain" />
      </StackPanel>
      

      代码

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

      您可以参考“http://wpftutorial.net/PasswordBox.html”了解详细信息。