Как связать PasswordBox с wpf в MVVM
Пожалуйста, скажите мне, как связать PasswordBox с wpf в MVVM
По соображениям безопасности WPF не давал никакого свойства зависимости в поле пароля. Как бы то ни было если вы действительно хотите достичь того чего хотите то вы можете следовать Сэмюэл Джек[^] сообщение в блоге, где он дал элегантное решение.
Проблема в том, что в PasswordBox нет свойства Idependency :S
Извините, попробуйте это ... http://www.wpftutorial.net/PasswordBox.html-да. Вам нужно использовать прикрепленное поведение.
Используйте приведенное ниже прилагаемое свойство для привязки поля пароля
<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); } }
<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>
Я потратил целую вечность, пытаясь заставить это работать. В конце концов я сдался и просто использовал DevExpress PasswordBoxEdit. Это позволяет связывать.
https://www.devexpress.com/Support/Center/Question/Details/Q506351[^]
Windows получает пароль от PasswordBox с помощью MVVM безопасным и простым способом образец в C#, XAML для Visual Studio 2013[^]
Этому вопросу уже более 6 лет, и он уже решен.
Не могли бы вы поделиться ссылкой , где я могу получить ответ.
В приведенных выше решениях есть несколько ссылок! Кто-то, использующий соответствующий поиск, должен найти документ MS, на который вы ссылаетесь, раньше, чем любое из приведенных здесь решений.
Если вам нужно найти ответ, почему вы опубликовали решение? (Кстати, это риторический вопрос)
<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>
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; } }
на ваш взгляд:
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>
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); }}
Почему бы не передать весь объект пароля в 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" */
private void SigningIn(object parameter) { PasswordBox PasswordObj= parameter as PasswordBox; string Password = password.Password;//here is the entered password }