Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C# property grid string editor

Tags:

c#

winforms

What is the easiest way to have Visual Studio-like editor for string in PropertyGrid? For example in Autos/Locals/Watches you can preview/edit string values in-line but you can also click on magnifying glass and see string in external window.

like image 744
John Avatar asked Aug 06 '11 21:08

John


1 Answers

You can do this via a UITypeEditor, as below. Here I'm using it on an individual property, but IIRC you can also subvert all strings (so that you don't need to decorate all the properties):

using System;
using System.ComponentModel;
using System.Drawing.Design;
using System.Windows.Forms;
using System.Windows.Forms.Design;

static class Program
{
    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        using(var frm = new Form { Controls = { new PropertyGrid {
            Dock = DockStyle.Fill, SelectedObject = new Foo { Bar = "abc"}}}})
        {
            Application.Run(frm);
        }
    }
}

class Foo
{
    [Editor(typeof(FancyStringEditor), typeof(UITypeEditor))]
    public string Bar { get; set; }
}
class FancyStringEditor : UITypeEditor
{
    public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
    {
        return UITypeEditorEditStyle.Modal;
    }
    public override object EditValue(ITypeDescriptorContext context, IServiceProvider provider, object value)
    {
        var svc = (IWindowsFormsEditorService)provider.GetService(typeof(IWindowsFormsEditorService));
        if (svc != null)
        {
            using (var frm = new Form { Text = "Your editor here"})
            using (var txt = new TextBox {  Text = (string)value, Dock = DockStyle.Fill, Multiline = true })
            using (var ok = new Button { Text = "OK", Dock = DockStyle.Bottom })
            {
                frm.Controls.Add(txt);
                frm.Controls.Add(ok);
                frm.AcceptButton = ok;
                ok.DialogResult = DialogResult.OK;
                if (svc.ShowDialog(frm) == DialogResult.OK)
                {
                    value = txt.Text;
                }
            }
        }
        return value;
    }
}

To apply this for all string members: instead of adding the [Editor(...)], apply the following somewhere early in the app:

TypeDescriptor.AddAttributes(typeof(string), new EditorAttribute(
     typeof(FancyStringEditor), typeof(UITypeEditor)));
like image 78
Marc Gravell Avatar answered Oct 12 '22 11:10

Marc Gravell