2016-10-10 2 views
1

У меня есть поле с паролем, который я добавляю кнопку «Показать пароль», чтобы (как показано на рисунке):Как получить выделенный текст в PasswordBox

enter image description here

Соответствующий XAML для пароля TextBox выглядит как это:

   <Border VerticalAlignment="Center" Grid.Row="2" Margin="2" Grid.Column="1" 
        BorderThickness="1" 
        BorderBrush="Black" 
        Background="White"> 
       <Grid> 
        <Grid.ColumnDefinitions> 
         <ColumnDefinition Width="*" /> 
         <ColumnDefinition Width="Auto" /> 
        </Grid.ColumnDefinitions> 
        <PasswordBox Name="txtPassword" Grid.Column="0" MaxLength="100" Margin="2" BorderThickness="0" GotFocus="txtPassword_GotFocus" PasswordChanged="txtPassword_PasswordChanged" /> 
        <TextBox Name="txtVisiblePassword" Grid.Column="0" MaxLength="100" Margin="2" BorderThickness="0" Visibility="Collapsed" Height="22" /> 
        <Button Grid.Column="1" Style="{StaticResource LightHoverButton}" x:Name="btnShowPassword" PreviewMouseDown="btnShowPassword_PreviewMouseDown" PreviewMouseUp="btnShowPassword_PreviewMouseUp"> 
         <Image Source="{StaticResource ShowPassword_128}" Style="{StaticResource Image_16}" Margin="3,0" /> 
        </Button> 
       </Grid> 
      </Border> 

Соответствующий код позади:

private void txtPassword_PasswordChanged(object sender, RoutedEventArgs e) 
    { 
     //Can show password is set to false if the password being displayed has been 
     //placed there automatically because the password is being remembered 
     if (canshowpassword == false && string.IsNullOrEmpty(txtPassword.Password)) 
      canshowpassword = true; 
     if (canshowpassword) 
      btnShowPassword.Visibility = string.IsNullOrEmpty(txtPassword.Password) ? Visibility.Collapsed : Visibility.Visible; 
     else 
      btnShowPassword.Visibility = Visibility.Collapsed; 
    } 

Проблема у меня есть, есть опция «запомнить пароль», и я не хочу, чтобы пользователь мог видеть пароль, если текстовое поле пароля не было «очищено» от всего текста хотя бы один раз (чтобы предотвратить видя все или часть пароля, который был автоматически помещен там). Вышеприведенный код близок, однако проблема заключается в том, что если пользователь выбирает весь текст, а затем нажимает клавишу, чтобы начать новый пароль, «пустой» пароль не проходит через событие с измененным паролем и кнопку «Показать пароль» не станет видимым. Пользователь должен удалить весь текст, а затем начать вводить текст еще раз. Я хотел бы уловить случай, когда пользователь выбирает весь текст и начинает печатать.

Если я просматриваю событие Key down, в PasswordBox отсутствует свойство SelectedText, поэтому я не знаю, как узнать заранее, будет ли пароль очищен до добавления нового текста.

Есть ли способ узнать, что пароль PasswordBox был очищен и/или узнать, выбран ли весь текст?

ответ

2

Это очень сложно. Они публично не раскрывают эту информацию, но вы можете получить ее с некоторым отражением. Это своего рода неприятный, потому что они пытаются скрыть все с внутренними классами и частной собственности, но здесь вы идете:

 TextSelection selection = (TextSelection)typeof(PasswordBox).GetProperty("Selection", BindingFlags.Instance | BindingFlags.NonPublic).GetMethod.Invoke(textBox, null); 

     Type tTextRange = selection.GetType().GetInterfaces().Where(x => x.Name == "ITextRange").FirstOrDefault(); 

     object oStart = tTextRange.GetProperty("Start").GetMethod.Invoke(selection, null); 
     object oEnd = tTextRange.GetProperty("End").GetMethod.Invoke(selection, null); 

     MethodInfo mi = oStart.GetType().GetProperty("Offset", BindingFlags.Instance | BindingFlags.NonPublic).GetMethod; 

     int nStart = (int)mi.Invoke(oStart, null); 
     int nEnd = (int)mi.Invoke(oEnd, null); 

     System.Diagnostics.Debug.WriteLine(nStart + " ==> " + nEnd); 

Вы должны, конечно, кэшировать некоторые вещи отражения, но я оставлю это до вас :).

ПРИМЕЧАНИЕ: вам нужно начать и завершить текст textBox_PreviewKeyDown(). К тому времени, как вы попадаете в PasswordChanged, выбор уже потерян, очевидно. Если вы хотите проверить, что весь пароль выбран, вы должны проверить на 0 ==> len.

Смежные вопросы