2

我有一个 wpf 应用程序,并且出于我无法控制的原因,我正在仔细遵循 mvvm 模式。出于我无法控制的安全原因,我不想将数据绑定到我的 PasswordBox。登录失败时如何清除密码框的内容?我更喜欢在 xaml 中这样做的方法。

4

1 回答 1

4

您可以创建附件 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(in Style/ DataTemplate/ etc) 一起使用:

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

Trigger(in 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);
}

完整示例:

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();
            }
        }
    }
}
于 2013-07-19T16:25:47.687 回答