gpt4 book ai didi

c# - 在 UserControl 中公开 DataGridView 的 Columns 属性并使其可通过 Designer 进行编辑

转载 作者:太空狗 更新时间:2023-10-29 21:32:42 24 4
gpt4 key购买 nike

Short description:

I have a UserControl with a DataGridView on it. I want to expose the DataGridView Columns collection to the designer, so I can change the columns on my User Control at design time.

问题:为此我需要哪些设计器属性?

对于那些对较长版本感兴趣的人:

我有一个具有以下功能的 UserControl:

  • 一个显示集合中项目“页面”的 DataGridView。
  • 一个 NumericUpdown 控件,用于选择要显示的页面。
  • 在显示第一页/最后一页时将禁用的向上翻页/向下翻页按钮
  • 对显示项目的更改在视觉上标记
  • 用于保存/放弃更改的按钮。

此用户控件可以自主工作。它有一个函数供父控件使用:

  • 显示页面(要显示的项目集合)

UserControl 引发两个事件:

  • 事件页面已更改(带有页码)。应导致加载新页面
  • 事件保存项(包含已更改项的集合)

我必须在多个表单上显示此用户控件。唯一的区别是 DataGridViewColumn 的集合因表单而异。

我可以通过编程方式添加列,但使用设计器创建它们会更容易。

最佳答案

通常注册一个合适的UITypeEditor就足够了使用 [Editor]属性。 DataGridView 使用的编辑器是 DataGridViewColumnCollectionEditor。但是在这种情况下,如果我们直接使用这个编辑器,编辑器期望属性属于 DataGridView 并尝试转换 ITypeDescriptorContext.Instance 的值。到 DataGridView 并且由于我们编辑 Columns 属性属于我们的用户控件,我们将收到一个异常:

Unable to cast object of type 'Type of Control' to type 'System.Windows.Forms.DataGridView'.

要解决这个问题,我们需要创建一个自定义的UITypeEditor 并覆盖EditValue并编辑用户控件的私有(private) DataGridView 字段的 Columns 属性。

为此,我们创建了一个 ITypeDescriptorContext 的实例包含 DataGridView 及其 Columns 属性并将其传递给编辑器的 EditValue 方法。这样,编辑器将编辑我们的 Columns 属性。

我们还使用 [DesignerSerializationVisibility] 装饰我们的属性(property)序列化集合内容的属性。

这里是实现。

我的用户控件

我假设您在设计时向用户控件添加了一个 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; }
}
}

编辑器

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;
}
}

ITypeDescriptionContext 实现

public class TypeDescriptionContext : ITypeDescriptorContext
{
private Control editingObject;
private PropertyDescriptor editingProperty;
public TypeDescriptionContext(Control obj, PropertyDescriptor property)
{
editingObject = obj;
editingProperty = property;
}
public IContainer Container
{
get { return editingObject.Container; }
}
public object Instance
{
get { return editingObject; }
}
public void OnComponentChanged()
{
}
public bool OnComponentChanging()
{
return true;
}
public PropertyDescriptor PropertyDescriptor
{
get { return editingProperty; }
}
public object GetService(Type serviceType)
{
return editingObject.Site.GetService(serviceType);
}
}

关于c# - 在 UserControl 中公开 DataGridView 的 Columns 属性并使其可通过 Designer 进行编辑,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36787383/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com