1

I have the next property on my user control:

[
    Browsable(true),
    Category("Data"),
    Description("Listado de controles que proporcionan los parámetros para generar el reporte."),
    DesignerSerializationVisibility(DesignerSerializationVisibility.Content)
]
public List<Control> ControlesParametros { set; get; }

I want to make Visual Studio to show me a editor where I can select some of the existing control instances in the form where I have placed my user control. Currently Visual Studio shows me an editor where I can add new controls, but not select the existing one.

I have found a similar question and answer, but the solution was a custom editor designed using .NET Framework 4.0, and I currently have 3.5: Design-time editor support for controls collection

Is there a native editor, or should I build one?

Community
  • 1
  • 1
Guillermo Gutiérrez
  • 17,273
  • 17
  • 89
  • 116

1 Answers1

0

For starters, I would use Collection<Control> instead of List<T>. A list will often work, but it does expose your collection in ways you may not want.

To get the existing controls, you need to dig into context.Container.Components in the LoadValues override. It will have everything including the host form itself and components, so you will likely have to filter them. One thing for certain is to remove components (like DataGridViewColumns and TabPages) as they wont go into a List or Collection of controls; other things like TableLayoutPanels you will often want to remove also.

This version filters out some components and controls for the default dropdown:

protected override void LoadValues(System.ComponentModel.ITypeDescriptorContext context, System.IServiceProvider provider, object value)
{

    bool bAdd = true;
    Control thisCtl = null;

    Collection<Control> tCollection = (Collection<Control>)value;

    foreach (object obj in context.Container.Components) {
        //Cycle through the components owned by the form in the designer
        bAdd = true;

        // exclude other components - this weeds out DataGridViewColumns which
        // can only be used by a DataGridView
        if (obj is Control) {
            thisCtl = (Control)obj;

            if (ExcludeForm) {
                bAdd = !(thisCtl is Form);
            }

            // custom exclude list 
            if ((typeExclude != null) && (typeExclude.Count > 0)) {
                if (typeExclude.Contains(thisCtl.GetType)) {
                    bAdd = false;
                }
            }

            bool bCheck = false;
            int ndx = 0;
            if (bAdd) {
                bCheck = tCollection.Contains(thisCtl);

                ndx = myCtl.Items.Add(new ListItem(thisCtl));
                myCtl.SetItemChecked(ndx, bCheck);
            }
        }

    }

}

enter image description here

If you prefer, you can display the eligible controls Dialog style and use a CheckedListBox for the user to pick controls. There is an article on CodeProject Selecting Form's Controls at Design Time which goes into more detail.

It is in VB, but allows you to easily implement such a beast pretty easily (I wrote it, so I may be biased):

ExampleDropDownControlCollectionUIEditor : ControlCollectionDropDownUIEditor
{
    public ExampleDropDownControlCollectionUIEditor() : base()
    {
        base.ExcludeForm = true;

        base.CheckControlWidth = 200;

        base.typeExclude.Add(typeof(RadioButton));
        base.typeExclude.Add(typeof(Label));
    }
}

The dialog form is as simple, just using a different base class, ControlCollectionDialogUIEditor

Ňɏssa Pøngjǣrdenlarp
  • 38,411
  • 12
  • 59
  • 178