Is it possible to mark a property shown in a property grid as a password field
Asked Answered
S

3

19

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.

Slovenia answered 14/1, 2009 at 15:44 Comment(0)
P
28

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

Hope this helps.

Panaggio answered 14/1, 2009 at 19:28 Comment(1)
Note that if you're adding this attribute to your code manually, to have the expected effect, it must be declared like [PasswordPropertyText(true)], rather than just [PasswordPropertyText]. The second version uses the default constructor, which sets the attribute's Password property to false, which means that the property grid ignores it.Endocrinology
C
1

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"}
                }
            }
        });
    }
}
Comminate answered 14/1, 2009 at 15:49 Comment(1)
The accepted answer says you can (do what the OP asked)!Disorder
V
1

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;
    }
}
Venison answered 14/1, 2009 at 15:58 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.