C# 如何创建打开表单的自定义 PropertyGrid 编辑器项目?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/1016239/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to create custom PropertyGrid editor item which opens a form?
提问by esac
I have a List<> (my custom class). I want to display a specific item in this list in a box on the PropertyGrid control. At the end of the box I would like the [...] button. When clicked, it would open up a form which, among other things, would allow them to pick one of the items from the List. When closed, the PropertyGrid would be updated to reflect the selected value.
我有一个 List<> (我的自定义类)。我想在 PropertyGrid 控件上的框中显示此列表中的特定项目。在框的末尾,我想要 [...] 按钮。当点击时,它会打开一个表单,除其他外,它允许他们从列表中选择一个项目。关闭时,PropertyGrid 将更新以反映所选值。
Any help appreciated.
任何帮助表示赞赏。
采纳答案by Marc Gravell
You need to implement a modal UITypeEditor
, using the IWindowsFormsEditorService
service to display it:
您需要实现一个 modal 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);
}
}
Note: if you need to access something about the context of the property (the parent object etc), that is what the ITypeDescriptorContext
(in EditValue
) provides; it tells you the PropertyDescriptor
and Instance
(the MyType
) that is involved.
注意:如果您需要访问有关属性上下文(父对象等)的内容,这就是ITypeDescriptorContext
(in EditValue
) 提供的内容;它告诉您所涉及的PropertyDescriptor
和Instance
(该MyType
)。