2016-07-27 66 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(); 
     } 
    }