【问题标题】:How to create custom PropertyGrid editor item which opens a form?如何创建打开表单的自定义 PropertyGrid 编辑器项?
【发布时间】:2010-11-04 05:07:07
【问题描述】:

我有一个 List(我的自定义类)。我想在 PropertyGrid 控件的框中显示此列表中的特定项目。在框的末尾,我想要 [...] 按钮。单击时,它会打开一个表单,除其他外,该表单将允许他们从列表中选择一个项目。关闭时,PropertyGrid 将更新以反映所选值。

任何帮助表示赞赏。

【问题讨论】:

    标签: c# winforms propertygrid


    【解决方案1】:

    你需要实现一个模态UITypeEditor,使用IWindowsFormsEditorService服务来显示它:

    using System.ComponentModel;
    using System.Drawing.Design;
    using System.Windows.Forms;
    using System.Windows.Forms.Design;
    using System;
    
    class MyType
    {
        private Foo foo = new Foo();
        public Foo Foo { get { return foo; } }
    }
    
    [Editor(typeof(FooEditor), typeof(UITypeEditor))]
    [TypeConverter(typeof(ExpandableObjectConverter))]
    class Foo
    {
        private string bar;
        public string Bar
        {
            get { return bar; }
            set { bar = value; }
        }
    }
    class FooEditor : UITypeEditor
    {
        public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
        {
            return UITypeEditorEditStyle.Modal;
        }
        public override object EditValue(ITypeDescriptorContext context, System.IServiceProvider provider, object value)
        {
            IWindowsFormsEditorService svc = provider.GetService(typeof(IWindowsFormsEditorService)) as IWindowsFormsEditorService;
            Foo foo = value as Foo;
            if (svc != null && foo != null)
            {            
                using (FooForm form = new FooForm())
                {
                    form.Value = foo.Bar;
                    if (svc.ShowDialog(form) == DialogResult.OK)
                    {
                        foo.Bar = form.Value; // update object
                    }
                }
            }
            return value; // can also replace the wrapper object here
        }
    }
    class FooForm : Form
    {
        private TextBox textbox;
        private Button okButton;
        public FooForm() {
            textbox = new TextBox();
            Controls.Add(textbox);
            okButton = new Button();
            okButton.Text = "OK";
            okButton.Dock = DockStyle.Bottom;
            okButton.DialogResult = DialogResult.OK;
            Controls.Add(okButton);
        }
        public string Value
        {
            get { return textbox.Text; }
            set { textbox.Text = value; }
        }
    }
    static class Program
    {
        [STAThread]
        static void Main()
        {
            Application.EnableVisualStyles();
            Form form = new Form();
            PropertyGrid grid = new PropertyGrid();
            grid.Dock = DockStyle.Fill;
            form.Controls.Add(grid);
            grid.SelectedObject = new MyType();
            Application.Run(form);
        }
    }
    

    注意:如果您需要访问有关属性上下文(父对象等)的某些内容,那是 ITypeDescriptorContext(在 EditValue 中)提供的;它会告诉您所涉及的PropertyDescriptorInstanceMyType)。

    【讨论】:

    • 我希望我可以 +1 两次!大约 2 年前,我在过去投了赞成票,然后我在另一个项目上再次回到同一个问题,但仍然发现它正是我所需要的。很好的答案,谢谢!
    • 一切看起来都不错,但 FooEditor 并没有在任何地方使用。对于某些属性,它应该设置为 TypeEditor。
    • @virious 类型编辑器可以针对属性或类型指定;在这种情况下,它(通过[Editor(typeof(FooEditor), typeof(UITypeEditor))])应用于Foo 类型。因此,Foo 类型的 every 属性默认使用此编辑器。请参阅示例中的MyType.Foo
    • 谢谢你的好例子!
    • 有没有办法访问网格所在的父窗口?我问是因为以 CenterOwner 身份启动新窗口会很好
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多