2016-07-27 2 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

попробуйте удалить 'Background = "Transparent"' – Venky

+0

@Venky не работает:/ – Ricardo

ответ

2

PasswordBox не имеет Text свойство, она имеет Password и SecurePassword свойства, которые не являются свойствами зависимостей - так что вы выиграли» t получить уведомление об изменении для них.

Что вы можете сделать, это определить вложенное свойство, что присоединяется к 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

Спасибо за ответ, таким образом, у меня какой-то проблемы в реализации. Я создал класс в папке «Ресурсы» и использовал его следующим образом: Ресурсы: PasswordBoxExtensions.IsActive = «True», но почему-то он не распознает. – Ricardo

+0

Вам нужно добавить 'xmlns' в корень XAML, например:' 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; 
    } 

ViewModel:

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(); 
     } 
    } 
Смежные вопросы