views:

1001

answers:

3

I'm using C# and have a windows form containing a property grid control.

I have assigned the SelectedObject of the propertygrid to a settings file, which displays and lets me edit the settings. However one of the settings is a password - and I'd like it to display asterisks in the field rather than the plain text value of the password setting.

The field will be encrypted when saved, but I want it to behave like a normal password entry box with asterisks displayed when the user is entering in the password.

I'm wondering if there is an attribute that can be applied to the setting property to mark it as being a password?

Thanks.

+2  A: 

I don't think you can get PropertyGrid to swap to asterisks, but you could perhaps use a one-way type-converter and a modal editor... like so:

using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;
class Foo
{
    [TypeConverter(typeof(PasswordConverter))]
    [Editor(typeof(PasswordEditor), typeof(UITypeEditor))]
    public string Password { get; set; }

    // just to show for debugging...
    public string PasswordActual { get { return Password; } }
}
class PasswordConverter : TypeConverter
{
    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, System.Type destinationType)
    {
        return destinationType == typeof(string) ? "********" : 
            base.ConvertTo(context, culture, value, destinationType);


    }
}
class PasswordEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        IWindowsFormsEditorService svc = (IWindowsFormsEditorService)
            provider.GetService(typeof(IWindowsFormsEditorService));
        if (svc != null) {
            TextBox tb;
            Button btn;
            Form frm = new Form { Controls = {
                 (tb = new TextBox { PasswordChar = '*', Dock = DockStyle.Top,
                     Text = (string)value}),
                 (btn = new Button { Text = "OK", Dock = DockStyle.Bottom, DialogResult = DialogResult.OK})
            }, AcceptButton = btn};

            if (frm.ShowDialog() == DialogResult.OK)
            {
                value = tb.Text;
            }
        }
        return value;
    }
}
static class Program {
    [STAThread]
    static void Main() {
        Application.EnableVisualStyles();
        Application.Run(new Form {
            Controls = {
                new PropertyGrid {
                    Dock = DockStyle.Fill,
                    SelectedObject = new Foo { Password = "Bar"}
                }
            }
        });
    }
}
Marc Gravell
+1  A: 

Here's what I've done in the past. It displays "****" for the password in the grid, with a "..." button to allow the user to set the password (using a dialog that you supply).

public class User
{
    [TypeConverter(typeof(PasswordConverter))]
    [Editor(typeof(PasswordEditor), typeof(UITypeEditor))]
    public string Password { get; set; }
}

public class PasswordConverter : TypeConverter
{
    public override bool CanConvertTo(ITypeDescriptorContext context, Type destinationType)
    {
        if (destinationType == typeof(string)) return true;

        return base.CanConvertTo(context, destinationType);
    }

    public override object ConvertTo(ITypeDescriptorContext context, System.Globalization.CultureInfo culture, object value, Type destinationType)
    {
        if (destinationType == typeof(string))
        {
            string password = (string)value;

            if (password != null && password.Length > 0)
            {
                return "********";
            }
        }

        return base.ConvertTo(context, culture, value, destinationType);
    }
}

public class PasswordEditor : UITypeEditor
{
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        string password = (string)value;

        // Show a dialog allowing the user to enter a password

        return password;
    }

    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }
}
Jon B
OK, that's pretty scary (comparison to mine, written independently)! The bit that took time was a few lines of code for a crude editor ;-p
Marc Gravell
I was hoping somebody would have a simpler solution, like the "HeyThisIsAPassword" attribute. Oh well :)
Jon B
+7  A: 

Starting with .Net 2, you can use the PasswordPropertyTextAttribute attached to your password property.

Hope this helps.

Nicolas Cadilhac
Fantastic Nicolas! That's exactly what I was looking for
Awesome,..just what i needed!
Stimul8d