Как получить пароль как SecureString от DevExpress WinForms TextEdit - PullRequest
0 голосов
/ 01 февраля 2011

WPF имеет PasswordBox, который получает ввод пароля в SecureString, но у меня есть приложение WinForms.Я могу использовать SecurePasswordTextBox , но я хочу что-то, что сочетается с элементами управления DevExpress и настройкой внешнего вида DevExpress.Для элемента управления DevExpress TextEdit вы можете установить UseSystemPasswordChar = true, но он не использует SecureString (и не будет: ср. 10/22/2010 , ср. Также .

Как я могу легко получить поддержку SecureString в элементе управления DevExpress WinForms TextEdit?

Я придумал что-то, что я опубликую ниже в качестве собственного ответа.

Редактировать: Я принимаю свой собственный ответ, который работает, потому что мне нужен внешний вид DevExpress.

Ответы [ 2 ]

1 голос
/ 01 февраля 2011

Вот мой собственный ответ:

Вместо того, чтобы создавать подклассы TextEdit, что кажется слишком сложным, я просто перехватываю события KeyPress и скрываю каждый нажатый символ до события EditValueChanging. Я храню уникальные токены в фальшивой строке, чтобы я мог выяснить, что нужно изменить в моей SecureString при каждом событии EditValueChanging.

Вот подтверждение концепции - простая форма с элементом управления TextEdit и двумя обработчиками событий:

public partial class PasswordForm : DevExpress.XtraEditors.XtraForm
{
    private Random random = new Random();
    private HashSet<char> pool = new HashSet<char>();
    private char secret;
    private char token;
    private List<char> fake = new List<char>();

    public PasswordForm()
    {
        InitializeComponent();
        this.Password = new SecureString();
        for (int i = 0; i < 128; i++)
        {
            this.pool.Add((char)(' ' + i));
        }
    }

    public SecureString Password { get; private set; }

    private void textEditPassword_EditValueChanging(object sender, DevExpress.XtraEditors.Controls.ChangingEventArgs e)
    {
        string value = e.NewValue as string;

        // If any characters have been deleted...
        foreach (char c in this.fake.ToArray())
        {
            if (value.IndexOf(c) == -1)
            {
                this.Password.RemoveAt(this.fake.IndexOf(c));
                this.fake.Remove(c);
                this.pool.Add(c);
            }
        }

        // If a character is being added...
        if (this.token != '\0')
        {
            int i = value.IndexOf(this.token);
            this.Password.InsertAt(i, this.secret);
            this.secret = '\0';
            fake.Insert(i, this.token);
        }
    }

    private void textEditPassword_KeyPress(object sender, KeyPressEventArgs e)
    {
        if (Char.IsControl(e.KeyChar))
        {
            this.token = '\0';
        }
        else
        {
            this.token = this.pool.ElementAt(random.Next(this.pool.Count)); // throws ArgumentOutOfRangeException when pool is empty
            this.pool.Remove(this.token);
            this.secret = e.KeyChar;
            e.KeyChar = this.token;
        }
    }
}
1 голос
/ 01 февраля 2011

Самый простой способ - использовать WPF PasswordBox, размещенный внутри ElementHost.

Вы можете перетащить элемент управления ElementHost из панели инструментов или сделать все это в коде:

public Form1()
{
    InitializeComponent();
    System.Windows.Forms.Integration.ElementHost host = new System.Windows.Forms.Integration.ElementHost();
    System.Windows.Controls.PasswordBox pb=new System.Windows.Controls.PasswordBox();
    host.Child =  pb;
    this.Controls.Add(host);
}

Конечно, это не использует элемент управления DevExpress, но я не вижу никакой причины для использования Rich Text Editor в качестве поля пароля, когда есть простая альтернатива.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...