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

PasswordBoxText 속성은 종속성 속성이 아닌 PasswordSecurePassword 특성을 가지고이없는 - 그래서 당신은 원 ' 그 (것)들을위한 어떤 변경 통보든지 얻으십시오.

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을 수행

은 당신이 할 수있는 일은 그것으로 PasswordChanged 이벤트와 바인드를 구독 연결된 속성을 정의하는 것입니다

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