Как очистить содержимое PasswordBox при сбое входа в систему без привязки данных?
У меня есть приложение wpf, и я тщательно следую шаблону mvvm по независящим от меня причинам. Я не хочу привязывать данные к моему PasswordBox по независящим от меня соображениям безопасности. Как очистить содержимое поля пароля в случае сбоя входа в систему? Я бы предпочел способ сделать это в xaml.
1 ответ
Решение
Вы можете создать свой прикрепленный DependencyProperty
и использовать его как XAML или в коде. Пример:
Листинг PasswordBehaviors
:
public static class PasswordBehaviors
{
public static void SetIsClear(DependencyObject target, bool value)
{
target.SetValue(IsClearProperty, value);
}
public static readonly DependencyProperty IsClearProperty =
DependencyProperty.RegisterAttached("IsClear",
typeof(bool),
typeof(PasswordBehaviors),
new UIPropertyMetadata(false, OnIsClear));
private static void OnIsClear(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is bool && ((bool)e.NewValue) == true)
{
PasswordBox MyPasswordBox = sender as PasswordBox;
if (MyPasswordBox != null)
{
MyPasswordBox.Clear();
}
}
}
}
Использование с EventTrigger
:
<EventTrigger SourceName="Clear" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyPasswordBox" Storyboard.TargetProperty="(local:PasswordBehaviors.IsClear)">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<sys:Boolean>True</sys:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
Использование с DataTrigger
(в Style
/DataTemplate
/etc
):
<DataTrigger Binding="{Binding ElementName=LoginElementFailed, Path=Status), Mode=OneWay}" Value="True">
<Setter Property="(local:PasswordBehaviors.IsClear)" Value="True" />
</DataTrigger>
Использование с Trigger
(в Style
):
<Trigger Property="LoginFailed.IsChecked" Value="True">
<Setter Property="(local:PasswordBehaviors.IsClear)" Value="True" />
</Trigger>
Использование за кодом:
private void Clear_Click(object sender, RoutedEventArgs e)
{
PasswordBehaviors.SetIsClear(MyPasswordBox, true);
}
Пример Copmlete:
XAML
<Window x:Class="ClearPasswordBox.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClearPasswordBox"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="MainWindow" Height="350" Width="525"
WindowStartupLocation="CenterScreen">
<Grid>
<Grid.Triggers>
<EventTrigger SourceName="Clear" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyPasswordBox" Storyboard.TargetProperty="(local:PasswordBehaviors.IsClear)">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<sys:Boolean>True</sys:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
<EventTrigger SourceName="ResetClear" RoutedEvent="Button.Click">
<BeginStoryboard>
<Storyboard>
<ObjectAnimationUsingKeyFrames Storyboard.TargetName="MyPasswordBox" Storyboard.TargetProperty="(local:PasswordBehaviors.IsClear)">
<DiscreteObjectKeyFrame KeyTime="0:0:0">
<DiscreteObjectKeyFrame.Value>
<sys:Boolean>False</sys:Boolean>
</DiscreteObjectKeyFrame.Value>
</DiscreteObjectKeyFrame>
</ObjectAnimationUsingKeyFrames>
</Storyboard>
</BeginStoryboard>
</EventTrigger>
</Grid.Triggers>
<PasswordBox Name="MyPasswordBox" local:PasswordBehaviors.IsClear="False" Width="100" Height="30" />
<Button Name="Clear" Width="100" Height="30" HorizontalAlignment="Right" Content="Clear" />
<Button Name="ResetClear" Width="100" Height="30" HorizontalAlignment="Left" Content="ResetClear" />
</Grid>
</Window>
Code behind
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
//private void Clear_Click(object sender, RoutedEventArgs e)
//{
// PasswordBehaviors.SetIsClear(MyPasswordBox, true);
//}
//private void ResetClear_Click(object sender, RoutedEventArgs e)
//{
// PasswordBehaviors.SetIsClear(MyPasswordBox, false);
//}
}
public static class PasswordBehaviors
{
public static void SetIsClear(DependencyObject target, bool value)
{
target.SetValue(IsClearProperty, value);
}
public static readonly DependencyProperty IsClearProperty =
DependencyProperty.RegisterAttached("IsClear",
typeof(bool),
typeof(PasswordBehaviors),
new UIPropertyMetadata(false, OnIsClear));
private static void OnIsClear(DependencyObject sender, DependencyPropertyChangedEventArgs e)
{
if (e.NewValue is bool && ((bool)e.NewValue) == true)
{
PasswordBox MyPasswordBox = sender as PasswordBox;
if (MyPasswordBox != null)
{
MyPasswordBox.Clear();
}
}
}
}