C# VS2008 Показать редактор, чтобы выбрать коллекцию существующих элементов управления во время разработки

У меня есть следующее свойство в моем пользовательском элементе управления:

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

Я хочу, чтобы Visual Studio показывал мне редактор, в котором я могу выбрать некоторые из существующих экземпляров элемента управления в форме, в которой я разместил свой пользовательский элемент управления. В настоящее время Visual Studio показывает мне редактор, где я могу добавлять новые элементы управления, но не выбирать существующий.

Я нашел похожий вопрос и ответ, но решением был пользовательский редактор, разработанный с использованием.NET Framework 4.0, и в настоящее время у меня есть 3.5: Поддержка редактора во время разработки для коллекции элементов управления

Есть ли собственный редактор или я должен его создать?

1 ответ

Для начала я бы использовал Collection<Control> вместо List<T>, Список часто будет работать, но он действительно выставляет вашу коллекцию так, как вы этого не хотите.

Чтобы получить существующие элементы управления, вам нужно покопаться в context.Container.Components в LoadValues переопределения. В нем будет все, включая саму форму хоста и компоненты, поэтому вам, вероятно, придется их фильтровать. Одно можно сказать наверняка, чтобы удалить компоненты (например, DataGridViewColumns а также TabPages) поскольку они не войдут в Список или Коллекцию элементов управления; другие вещи, такие как TableLayoutPanels, которые вы часто хотите удалить также.

Эта версия отфильтровывает некоторые компоненты и элементы управления для раскрывающегося списка по умолчанию:

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

    }

}

При желании вы можете отобразить подходящие элементы управления в стиле диалога и использовать CheckedListBox, чтобы пользователь мог выбрать элементы управления. В CodeProject есть статья " Выбор элементов управления формы во время разработки", которая более подробно описана.

Он есть в VB, но позволяет довольно легко реализовать такого зверя (я написал это, поэтому я могу быть предвзятым):

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

        base.CheckControlWidth = 200;

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

Форма диалога так же проста, просто с использованием другого базового класса, ControlCollectionDialogUIEditor

Другие вопросы по тегам