我实现了以下转换器和代码,目的是创建某种水印。此代码适用于TextBlock + TextBox,但不适用于TextBlock + PasswordBox。你知道为什么这个转换器不工作吗?

XAML

 <Helpers:HintConverter x:Key="hint" />
 <TextBlock Height="30" Text="                             password" Foreground="LightGray" Margin="274,264,278,306" Width="248">
        <TextBlock.Visibility>
            <MultiBinding Converter="{StaticResource hint}">
                <Binding ElementName="txtPassword" Path="Text.IsEmpty" />
                <Binding ElementName="txtPassword" Path="IsFocused" />
            </MultiBinding>
        </TextBlock.Visibility>
    </TextBlock>
    <PasswordBox PasswordChanged="PasswordBox_PasswordChanged" Name="txtPassword" BorderThickness="2" Height="30" Margin="273,264,275,306" Background="Transparent">
        <PasswordBox.BorderBrush>
            <LinearGradientBrush EndPoint="1,1" StartPoint="1,0">
                <GradientStop Color="White" Offset="0" />
                <GradientStop Color="White" Offset="0.75" />
                <GradientStop Color="Green" Offset="0.75" />
                <GradientStop Color="#FF0D9ECD" Offset="1" />
            </LinearGradientBrush>
        </PasswordBox.BorderBrush>
    </PasswordBox>

转换器
public class HintConverter : IMultiValueConverter
{
    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values[0] is bool && values[1] is bool)
        {
            bool hasText = !(bool)values[0];
            bool hasFocus = (bool)values[1];

            if (hasFocus || hasText)
                return Visibility.Collapsed;
        }
        return Visibility.Visible;
    }
    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

最佳答案

PasswordBox没有Text属性,它具有PasswordSecurePassword属性,它们不是依赖项属性-因此您不会收到任何更改通知。

您可以做的是定义一个附加属性,该属性订阅PasswordChanged事件并绑定(bind)到该事件:

public static class PasswordBoxExtensions
{
    public static readonly DependencyProperty IsActiveProperty =
        DependencyProperty.RegisterAttached(
            "IsActive", typeof(bool), typeof(PasswordBoxExtensions),
            new FrameworkPropertyMetadata(OnIsActiveChanged));

    private static void OnIsActiveChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        var passwordBox = d as PasswordBox;
        if (passwordBox == null) return;

        passwordBox.PasswordChanged -= OnPasswordChanged;
        if ((bool)e.NewValue)
        {
            SetIsPasswordEmpty(passwordBox);
            passwordBox.PasswordChanged += OnPasswordChanged;
        }
    }

    private static void OnPasswordChanged(object sender, RoutedEventArgs e)
    {
        SetIsPasswordEmpty((PasswordBox)sender);
    }

    public static void SetIsActive(PasswordBox element, bool value)
    {
        element.SetValue(IsActiveProperty, value);
    }

    public static bool GetIsActive(PasswordBox element)
    {
        return (bool)element.GetValue(IsActiveProperty);
    }

    public static readonly DependencyPropertyKey IsPasswordEmptyPropertyKey =
        DependencyProperty.RegisterAttachedReadOnly(
            "IsPasswordEmpty", typeof(bool), typeof(PasswordBoxExtensions),
            new FrameworkPropertyMetadata());

    public static readonly DependencyProperty IsPasswordEmptyProperty =
        IsPasswordEmptyPropertyKey.DependencyProperty;

    private static void SetIsPasswordEmpty(PasswordBox element)
    {
        element.SetValue(IsPasswordEmptyPropertyKey, element.SecurePassword.Length == 0);
    }

    public static bool GetIsPasswordEmpty(PasswordBox element)
    {
        return (bool)element.GetValue(IsPasswordEmptyProperty);
    }
}

用法:
<PasswordBox Name="txtPassword" app:PasswordBoxExtensions.IsActive="True" />


<Binding ElementName="txtPassword" Path="(app:PasswordBoxExtensions.IsPasswordEmpty)" />

关于c# - PasswordBox中的水印,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/38609797/

10-12 19:38