MVVM Passwordbox с шаблоном данных
Как я могу получить пароль из ящика паролей?
1. Я не хочу нарушать шаблон MVVM (по крайней мере, не слишком)
2. Я не могу использовать code-behind, потому что я использую шаблоны данных для создания своих представлений. Я должен использовать их, потому что я делаю окно, содержащее страницы. Поэтому я сохраняю модели просмотра страниц в моей модели окна просмотра и присоединяю их к ContentControl, когда мне нужно перейти к любому из них. Я должен сделать это, поскольку я делюсь своей моделью между ними.
3. Мне также нужен некоторый уровень безопасности, поэтому я не хочу "взламывать" поле пароля, чтобы связать свойство пароля.
Это невозможно?
Я не использую никаких MVVM-фреймворков. И я знаю, что есть много вопросов о passwordbox и MVVM, но ни один из них не касается шаблонов данных. Более того, у меня есть 2 поля ввода паролей (второе для "подтверждения пароля"), и я не могу просто передать PasswordBox как CommandParameter (потому что у меня их 2, и передача элемента, содержащего их, абсолютно варварская)
1 ответ
Серьезно, не существует настоящего решения mvvm для паролей, которое поддерживает безопасность, как без mvvm.
На мой взгляд, лучший / наименее плохой способ работы с полем паролей в приложении, построенном на mvvm, - это передать полный контроль над паролем вашей модели представления через параметр команды (как в кнопке входа / регистрации) и передать его своему внутреннему устройству. классы / услуги, пока вам действительно не понадобится получить пароль для веб-сервиса или чего-то в этом роде.
Это определенно нарушает шаблон mvvm, потому что ваша модель представления знает об элементе управления, но это самое безопасное решение, которое может быть легко внедрено в большинстве приложений, созданных mvvm.
РЕДАКТИРОВАТЬ: вы можете легко передать два или более паролей через параметр команды, если они вам нужны. (Как и в диалоговом окне регистрации, где пользователи должны ввести свой пароль два раза, и они должны совпадать.) Это можно сделать с помощью MultiBinding параметра Command:
<Button.CommandParameter>
<MultiBinding Converter="{local:ItemsToListConverter}">
<Binding ElementName="nameOfPasswordBox1" />
<Binding ElementName="nameOfPasswordBox2" />
</MultiBinding>
</Button.CommandParameter>
Конвертер просто возвращает все значения в виде нового списка:
[MarkupExtensionReturnType(typeof(ItemsToListConverter))]
public class ItemsToListConverter : MarkupExtension, IMultiValueConverter
{
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (values == null) return values;
return values.ToList();
}
public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
А в вашей ViewModel у вас есть обычная ICommand, которая принимает объект в качестве параметра. Вы можете привести этот объект к списку паролей. (В моем примере это RegisterCommand с методом "Register"):
private void Register(object obj)
{
IEnumerable<PasswordBox> passwordBoxes = (obj as IList).Cast<PasswordBox>();
//Do whatever with your PasswordBoxes =)
}