none
WPF: Подтверждение пароля RRS feed

  • Вопрос

  • Если 2 текстовых поля, в которые вводится пароль и подтверждение пароля. Как красиво сделать проверку одинаковости введенных паролей? Не хочу писать проверку в cs файле. Есть ощущение, что должно быть что-то наподобие ValidationRule, но пока не придумал как его прикрутить. Нужно чтобы просто подсвечивало текстовые поля красным.
    26 апреля 2011 г. 10:40
    Отвечающий

Ответы

  • Ну и задачку вы задали!!! Насчет красиво сомневаюсь, так как затраченные усилия оправдывает только повторное использование класса проверки ValidationRule, но мне показалось куда проще написать проверку соответствия пароля по старинке.

    Но в целях так сказать развития достигнутым поделюсь:

    1. Класс проверки:

     

    Public Class PasswordValidation
     Inherits Controls.ValidationRule
     Dim op As String
     Public WriteOnly Property OnePassword As String
      Set(ByVal value As String)
       op = value
      End Set
     End Property
     Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As System.Globalization.CultureInfo) As System.Windows.Controls.ValidationResult
      If CType(value, String) <> op Then
       Return New ValidationResult(False, "1111")
      Else
       Return New ValidationResult(True, vbNull)
      End If
     End Function
    End Class
    

     

    2. Простое тестовое окошко.

     

    <Window x:Class="MainWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:val="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="525">
     <Grid>
      <StackPanel>
       <TextBox Name="TB1" Margin="10" Text="{Binding ElementName=TwoPassword, Path=OnePassword, Mode=OneWayToSource}">   </TextBox>
       <TextBox Margin="10" Name="TB2">
        <TextBox.Text>
         <Binding ElementName="TB2" Path="ToolTip" Mode="OneWayToSource" UpdateSourceTrigger="PropertyChanged">
          <Binding.ValidationRules>
           <val:PasswordValidation x:Name="TwoPassword"></val:PasswordValidation>
          </Binding.ValidationRules>
         </Binding>
        </TextBox.Text>
       </TextBox>
      </StackPanel>
     </Grid>
    </Window>
    

     

    Вывод я сделал такой ValidationRule вещь хорошая, но не в данном случае.

    Другого красивого способа я не знаю, поэтому в случае с проверкой паролей останусь при старой методике, тем более что у PassworBox свойство Password не является свойством зависимости (((

     


    • Предложено в качестве ответа Abolmasov Dmitry 3 мая 2011 г. 21:09
    • Помечено в качестве ответа Abolmasov Dmitry 6 мая 2011 г. 7:11
    29 апреля 2011 г. 6:19
    Отвечающий

Все ответы

  • Хорошую тему вы подняли. Нужно подумать. Я пока что в коде проверяю соответствие полей и если не соответствуют запускаю анимацию для Backgraund, которая пару раз делает фон красным и возвращает обратно.
    26 апреля 2011 г. 11:23
    Отвечающий
  • Ну и задачку вы задали!!! Насчет красиво сомневаюсь, так как затраченные усилия оправдывает только повторное использование класса проверки ValidationRule, но мне показалось куда проще написать проверку соответствия пароля по старинке.

    Но в целях так сказать развития достигнутым поделюсь:

    1. Класс проверки:

     

    Public Class PasswordValidation
     Inherits Controls.ValidationRule
     Dim op As String
     Public WriteOnly Property OnePassword As String
      Set(ByVal value As String)
       op = value
      End Set
     End Property
     Public Overrides Function Validate(ByVal value As Object, ByVal cultureInfo As System.Globalization.CultureInfo) As System.Windows.Controls.ValidationResult
      If CType(value, String) <> op Then
       Return New ValidationResult(False, "1111")
      Else
       Return New ValidationResult(True, vbNull)
      End If
     End Function
    End Class
    

     

    2. Простое тестовое окошко.

     

    <Window x:Class="MainWindow"
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:val="clr-namespace:WpfApplication1" 
     Title="MainWindow" Height="350" Width="525">
     <Grid>
      <StackPanel>
       <TextBox Name="TB1" Margin="10" Text="{Binding ElementName=TwoPassword, Path=OnePassword, Mode=OneWayToSource}">   </TextBox>
       <TextBox Margin="10" Name="TB2">
        <TextBox.Text>
         <Binding ElementName="TB2" Path="ToolTip" Mode="OneWayToSource" UpdateSourceTrigger="PropertyChanged">
          <Binding.ValidationRules>
           <val:PasswordValidation x:Name="TwoPassword"></val:PasswordValidation>
          </Binding.ValidationRules>
         </Binding>
        </TextBox.Text>
       </TextBox>
      </StackPanel>
     </Grid>
    </Window>
    

     

    Вывод я сделал такой ValidationRule вещь хорошая, но не в данном случае.

    Другого красивого способа я не знаю, поэтому в случае с проверкой паролей останусь при старой методике, тем более что у PassworBox свойство Password не является свойством зависимости (((

     


    • Предложено в качестве ответа Abolmasov Dmitry 3 мая 2011 г. 21:09
    • Помечено в качестве ответа Abolmasov Dmitry 6 мая 2011 г. 7:11
    29 апреля 2011 г. 6:19
    Отвечающий
  • Anton.Maksimov, пожалуйста не оставляйте топик без ответа. Посмотрите вариант LXGDARK. Не забудьте ответить или отметить ответ. Спасибо.
    Для связи [mail]
  • Ещё вариант, что мне пришел в голову - это создание своего элемента, который ссылается на PasswordBox:

     public class PasswordValidator : FrameworkElement
     {
      static IDictionary<PasswordBox, Brush> _passwordBoxes = new Dictionary<PasswordBox, Brush>();
    
      public static readonly DependencyProperty Box1Property = DependencyProperty.Register("Box1", typeof(PasswordBox), typeof(PasswordValidator), new PropertyMetadata(Box1Changed));
      public static readonly DependencyProperty Box2Property = DependencyProperty.Register("Box2", typeof(PasswordBox), typeof(PasswordValidator), new PropertyMetadata(Box2Changed));
    
      public PasswordBox Box1
      {
       get { return (PasswordBox)GetValue(Box1Property); }
       set { SetValue(Box1Property, value); }
      }
      public PasswordBox Box2
      {
       get { return (PasswordBox)GetValue(Box2Property); }
       set { SetValue(Box2Property, value); }
      }
    
      private static void Box1Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
      }
      private static void Box2Changed(DependencyObject d, DependencyPropertyChangedEventArgs e)
      {
       var pv = (PasswordValidator)d;
       _passwordBoxes[pv.Box2] = pv.Box2.BorderBrush;
       pv.Box2.LostFocus += (obj, evt) =>
       {
        if (pv.Box1.Password != pv.Box2.Password)
        {
         pv.Box2.BorderBrush = new SolidColorBrush(Colors.Red);
        }
        else
        {
         pv.Box2.BorderBrush = _passwordBoxes[pv.Box2];
        }
       };
      }
     }
    

    И в xaml прописывается так:

    <PasswordBox Name="tbPassword" />
    <PasswordBox Name="tbPasswordConf" />
    <PasswordValidator Box1="{Binding ElementName=tbPassword}" Box2="{Binding ElementName=tbPasswordConf}" />
    

    Минус такого подхода в том, что не используется стандартный ErrorTemplate, что правда, вместо Brush можно сохранять стиль и сделать ещё одну Dependency Property, в которую будет передаваться ErrorStyle. Теоретически, можно пойти по пути ValidationRule и добавлять ошибки в элемент управления и очищать их, но я не придумал как это сделать, поскольку класс Validation не дает ими манипулировать явно.

    В моем случае переиспользование кода есть. Спасибо за помощь.


    Отвечающий