如何从DevExpress WinForms TextEdit获取密码作为SecureString

如何从DevExpress WinForms TextEdit获取密码作为SecureString,winforms,security,devexpress,Winforms,Security,Devexpress,WPF有一个PasswordBox,它将密码输入到SecureString中,但我有一个WinForms应用程序。我可以使用,但我想要一些与DevExpress控件和DevExpress外观定制相结合的东西。在DevExpress文本编辑控件上,您可以设置UseSystemPasswordChar=true,但它不使用SecureString(并且不会:,) 如何将SecureString支持轻松添加到DevExpress WinForms TextEdit控件中 我想出了一个办法,我把它作为我

WPF有一个PasswordBox,它将密码输入到SecureString中,但我有一个WinForms应用程序。我可以使用,但我想要一些与DevExpress控件和DevExpress外观定制相结合的东西。在DevExpress文本编辑控件上,您可以设置UseSystemPasswordChar=true,但它不使用SecureString(并且不会:,)

如何将SecureString支持轻松添加到DevExpress WinForms TextEdit控件中

我想出了一个办法,我把它作为我自己的答案贴在下面。还有其他人有解决办法吗


编辑:我接受我自己的答案,这很有效,因为我需要DevExpress的外观。

最简单的方法是使用托管在ElementHost中的WPF密码箱

您可以从工具箱中拖动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控件,但我看不出有任何理由在有简单替代方案的情况下使用富文本编辑器作为密码框。

以下是我自己的答案:

我没有将TextEdit子类化(这看起来太复杂了),而是捕获按键事件并将每个按下的字符隐藏起来,直到EditValueChanged事件发生。我将唯一的标记保存在一个伪字符串中,这样我就可以在每个EditValueChangeing事件中找出要在SecureString中更改的内容

以下是概念证明——一个简单的表单,包含一个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;
        }
    }
}
公共部分类密码形式:DevExpress.XtraEditors.XtraForm
{
私有随机=新随机();
私有HashSet池=新HashSet();
私密性;
私有字符令牌;
私有列表fake=新列表();
公共密码形式()
{
初始化组件();
this.Password=new SecureString();
对于(int i=0;i<128;i++)
{
此.pool.Add((char)(''+i));
}
}
公共SecureString密码{get;private set;}
私有void textEditPassword\u editValueChangeing(对象发送者,DevExpress.XtraEditors.Controls.ChangingEventArgs e)
{
字符串值=e.NewValue作为字符串;
//如果已删除任何字符。。。
foreach(这个.false.ToArray()中的字符c)
{
if(值IndexOf(c)=-1)
{
this.Password.RemoveAt(this.fake.IndexOf(c));
这个。假的。去掉(c);
本.池.加(c);
}
}
//如果正在添加字符。。。
如果(this.token!='\0')
{
int i=value.IndexOf(this.token);
this.Password.InsertAt(i,this.secret);
this.secret='\0';
假。插入(i,此。令牌);
}
}
私有无效文本编辑密码\u按键(对象发送者,按键事件参数e)
{
if(Char.IsControl(e.KeyChar))
{
this.token='\0';
}
其他的
{
this.token=this.pool.ElementAt(random.Next(this.pool.Count));//当池为空时抛出ArgumentOutOfRangeException
this.pool.Remove(this.token);
this.secret=e.KeyChar;
e、 KeyChar=this.token;
}
}
}

虽然我丢失了DevExpress外观行为,但这很容易。我会尝试一下,看看它的外观如何。我使用的是DevExpress.XtraEditors.TextEdit,它是一个简单的单行编辑器,不是富格文本,但如果有现成的SecureString功能会更好。抱歉,我没有意识到这是您想要的DevExpress样式保存。