我实现了以下转换器和代码,目的是创建一些水印。此代码适用于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();
}
}
答案 0 :(得分:2)
PasswordBox
没有Text
属性,它有Password
和SecurePassword
属性,这些属性不是依赖属性 - 因此您不会收到任何更改通知对他们来说。
您可以做的是定义一个附加属性,该属性订阅PasswordChanged
事件并绑定到它:
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)" />
答案 1 :(得分:0)
我接下来
XAML:
<PasswordBox Name="PasswordBox"
PasswordChanged="PasswordBox_OnPasswordChanged"/>
<TextBlock Text="PASSWORD"
IsHitTestVisible="False">
<TextBlock.Style>
<Style TargetType="TextBlock" BasedOn="{StaticResource WatermarkStyle}">
<Style.Triggers>
<DataTrigger Binding="{Binding IsPasswordWatermarkVisible}" Value="False">
<Setter Property="Visibility" Value="Collapsed" />
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
代码隐藏:
private MyViewModel ViewModel
{
get { return (MyViewModel) DataContext; }
}
private void PasswordBox_OnPasswordChanged(object sender, RoutedEventArgs e)
{
ViewModel.Password = PasswordBox.Password;
}
视图模型:
public string Password
{
get { return _password; }
set
{
_password = value;
IsPasswordWatermarkVisible = string.IsNullOrEmpty(_password);
}
}
public bool IsPasswordWatermarkVisible
{
get { return _isPasswordWatermarkVisible; }
set
{
if (value.Equals(_isPasswordWatermarkVisible)) return;
_isPasswordWatermarkVisible = value;
OnPropertyChanged();
}
}