Как очистить содержимое 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>

Использование с DataTriggerStyle/DataTemplate/etc):

<DataTrigger Binding="{Binding ElementName=LoginElementFailed, Path=Status), Mode=OneWay}" Value="True">
    <Setter Property="(local:PasswordBehaviors.IsClear)" Value="True" />
</DataTrigger>

Использование с TriggerStyle):

<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();
            }
        }
    }
}
Другие вопросы по тегам