kayani29 Ответов: 9

Как связать PasswordBox с wpf в MVVM


Пожалуйста, скажите мне, как связать PasswordBox с wpf в MVVM

9 Ответов

Рейтинг:
2

Mahmudul Haque Azad

По соображениям безопасности WPF не давал никакого свойства зависимости в поле пароля. Как бы то ни было если вы действительно хотите достичь того чего хотите то вы можете следовать Сэмюэл Джек[^] сообщение в блоге, где он дал элегантное решение.


Рейтинг:
2

kayani29

Проблема в том, что в PasswordBox нет свойства Idependency :S


Abhinav S

Извините, попробуйте это ... http://www.wpftutorial.net/PasswordBox.html-да. Вам нужно использовать прикрепленное поведение.

Рейтинг:
1

hari111r

Используйте приведенное ниже прилагаемое свойство для привязки поля пароля

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

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

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


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

    }

Добавьте пространство имен вложенного свойства ("here util:") и используйте его, как показано ниже:
<passwordbox x:name="TxtPassword" util:boundpasswordbox.attach="True" util:boundpasswordbox.password="{Binding Path=Password,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged,ValidatesOnDataErrors=True,NotifyOnValidationError=True}" xmlns:util="#unknown" xmlns:x="#unknown">
</passwordbox>


Рейтинг:
1

smt52

Я потратил целую вечность, пытаясь заставить это работать. В конце концов я сдался и просто использовал DevExpress PasswordBoxEdit. Это позволяет связывать.

https://www.devexpress.com/Support/Center/Question/Details/Q506351[^]


Рейтинг:
1

CHill60

Этому вопросу уже более 6 лет, и он уже решен.

pitambar sahoo

Не могли бы вы поделиться ссылкой , где я могу получить ответ.

CHill60

В приведенных выше решениях есть несколько ссылок! Кто-то, использующий соответствующий поиск, должен найти документ MS, на который вы ссылаетесь, раньше, чем любое из приведенных здесь решений.
Если вам нужно найти ответ, почему вы опубликовали решение? (Кстати, это риторический вопрос)

Рейтинг:
1

Member 13329415

<PasswordBox x:Name="txtPassword" Margin="0,10" materialDesign:HintAssist.Hint="Password" Style="{StaticResource MaterialDesignFloatingHintPasswordBox}" FontFamily="Champagne & Limousines" FontSize="18" PasswordChanged="txtPassword_PasswordChanged">
                        <PasswordBox.DataContext>
                            <Binding Path="Password" UpdateSourceTrigger="PropertyChanged">
                                <Binding.ValidationRules>
                                    <demo:NotEmptyValidationRule ValidatesOnTargetUpdated="True" />
                                </Binding.ValidationRules>
                            </Binding>
                        </PasswordBox.DataContext>
                    </PasswordBox>


код cs:

private void txtPassword_PasswordChanged(object sender, RoutedEventArgs e)
       {

           loginViewModel.Password = txtPassword.Password;
           loginViewModel.UserName = txtUserName.Text;
           DataContext = loginViewModel;
       }



Вызов Файла Класса:
public class LoginViewModel : INotifyPropertyChanged
  {
      private string _UserName;
      private string _Password;
      public LoginViewModel()
      {
          LongListToTestComboVirtualization = new List<int>(Enumerable.Range(0, 1000));
      }
      public string UserName
      {
          get { return _UserName; }
          set
          {
              this.MutateVerbose(ref _UserName, value, RaisePropertyChanged());
          }
      }
      public string Password
      {
          get { return _Password; }
          set
          {
              this.MutateVerbose(ref _Password, value, RaisePropertyChanged());
          }
      }

      public IList<int> LongListToTestComboVirtualization { get; }

      public DemoItem DemoItem => new DemoItem("Mr. Test", null, Enumerable.Empty<DocumentationLink>());

      public event PropertyChangedEventHandler PropertyChanged;

      private Action<PropertyChangedEventArgs> RaisePropertyChanged()
      {
          return args => PropertyChanged?.Invoke(this, args);
      }
  }




Для Класса Валидации:

public class NotEmptyValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, CultureInfo cultureInfo)
        {
            return string.IsNullOrWhiteSpace((value ?? "").ToString())
                ? new ValidationResult(false, "Field is required.")
                : ValidationResult.ValidResult;
            
        }
    }


Рейтинг:
0

notonlyquestions

на ваш взгляд:

xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"

....

<PasswordBox Grid.Column="1" PasswordChar="*" x:Name="pwbox"     Password="test"   >
                      <i:Interaction.Triggers>
                          <i:EventTrigger EventName="PasswordChanged" >
                              <i:InvokeCommandAction Command="{Binding PasswordChangedCommand }"  CommandParameter="{Binding ElementName=pwbox,  Mode=OneWay}"/>
                          </i:EventTrigger>
                      </i:Interaction.Triggers>
                  </PasswordBox>





В ViewModel(который является DataContext вашего представления):

public ICommand PasswordChangedCommand
    {
        get
        {
            return new RelayCommand<object>(ExecChangePassword);
        }
    }

  

    private void ExecChangePassword(object obj)
    {
        yourPassword = ((System.Windows.Controls.PasswordBox)obj).Password;
    }



Какой-то другой класс...
public class RelayCommand<T> : ICommand
{

 
 
    /// <param name="execute">The execution logic.</param>
    public RelayCommand(Action<T> execute)
        : this(execute, null)
    {
    }
      public void Execute(Object parameter)
        {
            _execute((T)parameter);
        }}


Рейтинг:
0

Abhinav S

Вы могли бы начать с этот[^] статья.


Рейтинг:
0

Silent Guardian

Почему бы не передать весь объект пароля в ViewModel?Я думаю, что там также есть кнопка входа или отправки. передайте объект passwordbox с помощью кнопки submit(как commandparameter).

<passwordbox name="password" />
<button>
<interactivity:interaction.triggers xmlns:interactivity="#unknown">
<interactivity:eventtrigger eventname="Click">
<cmd:eventtocommand command="{Binding SignIn}" commandparameter="{Binding ElementName=password}" xmlns:cmd="#unknown" />
</interactivity:eventtrigger>
</interactivity:interaction.triggers>
</button>
/*
xmlns:interactivity="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
*/


Затем приведите его к объекту Passwordbox в ViewModel
private void SigningIn(object parameter)
{
PasswordBox PasswordObj= parameter as PasswordBox;
string Password = password.Password;//here is the entered password
}