简短说明:
我有一个带有DataGridView的UserControl。一世 想要将DataGridView Columns集合暴露给设计者,所以 我可以在设计时更改用户控件上的列。
问题:我需要哪些设计师属性?
对于那些对较长版本感兴趣的人:
我有一个具有以下功能的UserControl:
此用户控件可以自动运行。它有一个由父控件使用的函数:
UserControl引发了两个事件:
我必须在几个表单上显示此用户控件。唯一的区别是DataGridViewColumn的集合因形式而异。
我可以通过编程方式添加列,但使用设计器创建它们会更容易。
答案 0 :(得分:3)
通常使用UITypeEditor
属性注册合适的Editor
就足够了。 DataGridView
使用的编辑器是DataGridViewColumnCollectionEditor
。但在这种情况下,如果我们直接使用此编辑器,编辑器会期望该属性属于DataGridView
,并尝试将ITypeDescriptorContext.Instance
的值转换为DataGridVeiew
,因为我们正在编辑{{1属性属于我们的用户控件,我们将收到一个异常:
无法将'
Columns
类型的对象强制转换为类型 'Type of Control'
'
要解决此问题,我们需要创建自定义System.Windows.Forms.DataGridView
并覆盖UITypeEditor
并修改用户控件的私有EditValue
字段的Columns
属性。
为此,我们创建了一个DataGridView
的实例,其中包含ITypeDescriptorContext
及其DataGridView
属性,并将其传递给编辑器的Columns
方法。这样编辑器就会编辑我们的EditValue
属性。
我们还使用Columns
属性装饰我们的属性以序列化集合内容。
以下是实施。
<强>的MyUserControl 强>
我想您在设计时向用户控件添加[DesignerSerializationVisibility]
,其名称为DataGridView
。
dataGridView1
<强>编辑强>
public partial class MyUserControl : UserControl
{
public MyUserControl()
{
InitializeComponent();
}
[Editor(typeof(MyColumnEditor), typeof(UITypeEditor))]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Content)]
public DataGridViewColumnCollection Columns
{
get { return this.dataGridView1.Columns; }
}
}
ITypeDescriptionContext实施
public class MyColumnEditor : UITypeEditor
{
public override UITypeEditorEditStyle GetEditStyle(ITypeDescriptorContext context)
{
return UITypeEditorEditStyle.Modal;
}
public override object EditValue(ITypeDescriptorContext context,
IServiceProvider provider, object value)
{
var field = context.Instance.GetType().GetField("dataGridView1",
System.Reflection.BindingFlags.NonPublic |
System.Reflection.BindingFlags.Instance);
var dataGridView1 = (DataGridView)field.GetValue(context.Instance);
dataGridView1.Site = ((Control)context.Instance).Site;
var columnsProperty = TypeDescriptor.GetProperties(dataGridView1)["Columns"];
var tdc = new TypeDescriptionContext(dataGridView1, columnsProperty);
var editor = (UITypeEditor)columnsProperty.GetEditor(typeof(UITypeEditor));
var result = editor.EditValue(tdc, provider, value);
dataGridView1.Site = null;
return result;
}
}