2016-07-27 67 views
2

我已经实现了以下转换器和代码,目的是创建一些水印。此代码适用于TextBlock + TextBox,但不适用于TextBlock + PasswordBox。你知道为什么这个转换器不工作吗?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

尝试删除'背景= “透明”' – Venky

+0

@Venky不起作用:用于接听/ – Ricardo

回答

2

PasswordBox没有Text属性,它有PasswordSecurePassword性质,这是不依赖特性 - 这样你就赢了”没有任何变化通知他们。

你可以做的是定义一个附加属性,订阅到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)" /> 
+0

谢谢,因此我有一些实施中的问题。我已经在Resources文件夹中创建了这个类,并且像这样使用了:Resources:PasswordBoxExtensions.IsActive =“True”,但不知何故它无法识别。 – Ricardo

+0

您需要在XAML的根目录添加一个'xmlns',例如:'xmlns:Resources =“clr-namespace:YourNamespace.Resources”'(用应用程序的名称空间替换'YourNamespace'。 –

+0

已经做到了。 xmlns:Resources =“clr-namespace:Wpfv0.Resources”仍然没有任何内容:x – Ricardo

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