Expose Columns of the DataGridView property in UserControl and make it editable via Designer

Short description:

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

Question: What designer attributes do I need for this?

For those interested in the longer version:

I have a UserControl with the following features:

  • A DataGridView that shows the "pages" of items from the collection.
  • NumericUpdown element to choose which page to display.
  • up / down buttons of the page that will be disabled when the first / last page is displayed.
  • Changes to displayed items are visually marked.
  • Buttons for saving / canceling changes.

. , :

  • ( )

UserControl :

  • ( ).
  • ( )

. , DataGridViewColumn .

, .

+6
1

, UITypeEditor [Editor]. , DataGridView, DataGridViewColumnCollectionEditor. , , , DataGridView, ITypeDescriptorContext.Instance DataGridVeiew, Columns , :

'Type of Control' "System.Windows.Forms.DataGridView.

, UITypeEditor EditValue Columns DataGridView .

ITypeDescriptorContext, DataGridView Columns, EditValue . , Columns.

, [DesignerSerializationVisibility] .

.

MyUserControl

, 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);
    }
}
+6

All Articles