暴露DataGridView的Columns属性的用户控件,并使其通过设计可编辑 [英] Expose Columns property of a DataGridView in UserControl and make it editable via Designer

查看:544
本文介绍了暴露DataGridView的Columns属性的用户控件,并使其通过设计可编辑的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

简短说明:

我有它一个DataGridView一个用户控件。我
要到DataGridView Columns集合暴露给设计师,所以
我可以改变在设计时我的用户控制的列。

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.

问:哪些设计师的属性,我需要为这个

对于那些有兴趣在更长的版本:

For those interested in the longer version:

我有以下功能的用户控件:

I have a UserControl with the following features:


  • 一个DataGridView,显示页面从收集的物品。

  • NumericUpDown控件来选择显示哪个页面。

  • 页上/下翻页按钮,将禁用当第一/最后一页显示

  • 更改显示的项目将在视觉标记

  • 按钮保存/放弃更改。

  • a DataGridView that shows "pages" of items from a collection.
  • a NumericUpdown control to select which page to show.
  • page up / page down buttons that will disable when the first / last page is shown
  • Changes to the displayed items are visually marked
  • Buttons to save / discard the changes.

这个用户控件可以工作自主。它必须由家长控制使用的一个功能:

This user control can work autonomic. It has one function to be used by the parent control:


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

在用户控件引发两个事件:

The UserControl raises two events:


  • 活动页面改变(与页码)。应导致加载新页

  • 事件保存项目(以更改项目的集合)

我要展示几种形式这个用户的控制。唯一的区别是,的DataGridViewColumn收集每个表单不同。

I have to show this user control on several forms. The only difference is that the collection of DataGridViewColumn differs per form.

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

I could add the columns programmatically, but it would be easier to create them using the designer.

推荐答案

通常这足以注册一个合适的 UITypeEditor的使用编辑属性。其中所使用的 DataGridView的编辑器是 DataGridViewColumnCollectionEditor 。但在这种情况下,如果我们直接使用这个编辑器,编辑器预计的财产属于 DataGridView的,并尝试转换的的 ITypeDescriptorContext.Instance DataGridVeiew 键,因为我们的编辑属性属于我们的用户控件,我们将收到一个异常:

Usually it's enough to register a suitable UITypeEditor using Editor attribute. The editor which is used by the DataGridView is DataGridViewColumnCollectionEditor. But in this case, if we use this editor directly, the editor expect the the property belong to a DataGridView and tries to convert value of ITypeDescriptorContext.Instance to DataGridVeiew and since our editing Columns property belongs to our user control we will receive an exception:

无法投类型的对象控制的类型键入
' System.Windows.Forms.DataGridView

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

要解决这个问题,我们需要创建一个自定义的 UITypeEditor的和覆盖的EditValue 和编辑私人 DataGridView的用户控制领域的财产。

To solve the problem, we need to create a custom UITypeEditor and override EditValue and edit Columns property of the private DataGridView field of your user control.

要做到这一点,我们创建 ITypeDescriptorContext 中包含 DataGridView的<一个实例/ code>,它是属性并将其传递给的EditValue 编辑方法。这样,编辑器编辑我们的属性。

To do so, we create an instance of ITypeDescriptorContext containing the DataGridView and it's Columns property and pass it to EditValue method of the editor. This way the editor will edit our Columns property.

我们也使用装点我们的财产 [DesignerSerializationVisibility] 属性序列化的集合内容。

We also decorate our property using [DesignerSerializationVisibility] attribute to serialize the collection contents.

下面是实施

的MyUserControl

我想你添加 DataGridView的在设计时的用户控制和它的名字将是 dataGridView1

I suppose you add a DataGridView at design-time to the user control and its name would be 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);
    }
}

这篇关于暴露DataGridView的Columns属性的用户控件,并使其通过设计可编辑的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆