Поддержка редактора времени разработки для коллекции элементов управления

StackOverflow https://stackoverflow.com/questions/1372691

Вопрос

Я хотел бы добавить свойство, представляющее коллекцию элементов управления, к компоненту и иметь редактор коллекций, с помощью которого я мог бы легко выбирать элементы управления, принадлежащие коллекции.VS делает почти то, что я хочу, автоматически выполняется со следующим кодом:

    Private _controls As New List(Of Control)
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    Public ReadOnly Property SelectedControls() As List(Of Control)
        Get
            Return _controls
        End Get
    End Property

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

Проблема в том, что я не хочу добавлять новое элементы управления, я хочу выбрать несколько элементов управления из других доступных элементов управления в форме.Есть ли какой-нибудь простой / стандартный способ сделать это, или мне придется написать свой собственный редактор коллекций и запустить через коллекцию элементов управления?

Хотя существует множество материалов по редакторам коллекций (UITypeEditors) и другим темам, связанным с разработкой, я не смог найти никаких ссылок, демонстрирующих именно это поведение, поэтому приветствуется любая помощь.

Это было полезно?

Решение

Итак, тем временем я пообедал и сам написал редактору.Это было не такое уж большое усилие.Я был бы рад поделиться, если это поможет.

Редактировать:Краткое описание решения

Я написал редактор (см. Скриншот), который рекурсивно перечисляет все элементы управления, найденные в форме, в виде дерева.Если для элементов управления заданы свойства текста или изображения, отображается текст / изображение.Пользователь может выбрать несколько элементов управления с помощью флажков и даже отфильтровать список, чтобы отображать только элементы управления определенных типов.

(Однако я должен признать, что, поскольку этот редактор предназначался только для внутреннего использования, я не стал утруждать себя проверкой свойства image в общем виде, я просто обрабатываю пару хорошо известных типов элементов управления.)

alt text

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

Далее, у нас есть класс, который реализует UITypeEditor, который я назвал FormControlSelectionEditor .Этот класс присваивается свойствам, которые мы хотим использовать в редакторе для использования атрибута [Editor].Это не намного больше, чем создать новый экземпляр формы, когда требуется, и отобразить его в виде модального диалогового окна.

Затем есть сами свойства, которые относятся к типу System.Коллекции.Объектная модель.Наблюдаемая коллекция (элемента управления).Я выбрал ObservableCollection, потому что мне также нужно реагировать на изменения в списках во время выполнения, но другие списки будут работать так же хорошо с незначительной адаптацией.

Одна вещь, которую я обнаружил, - это то, что мне пришлось написать свои свойства и редактор таким образом, чтобы они использовали копии списков элементов управления.Другими словами, код UITypeEditor создает копию списка, хранящегося в свойстве, и передает его в форму редактора (для установки проверок при открытии формы), а когда форма закрывается, я очищаю резервный список свойства и копирую каждый элемент управления в списке, возвращенном из редактора.Я обнаружил, что в противном случае у меня возникли проблемы с сериализацией в файле .designer .Я не верю, что так должно быть;Я думаю, что это, скорее всего, ошибка с моей стороны.

Код для типичного свойства:

    Private WithEvents _insertButtons As New System.Collections.ObjectModel.ObservableCollection(Of Control)
    <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
    <Editor(GetType(Design.FormControlSelectionEditor), GetType(UITypeEditor))> _
    Public Property InsertButtons() As System.Collections.ObjectModel.ObservableCollection(Of Control)
        Get
            Return _insertButtons
        End Get
        Set(ByVal value As System.Collections.ObjectModel.ObservableCollection(Of Control))
            If value Is Nothing Then
                RemoveInsertButtonEventHandlers(_insertButtons)
                _insertButtons.Clear()
            Else
                ' Copy the list items passed in into the internal list
                For i As Integer = _insertButtons.Count - 1 To 0 Step -1
                    If Not value.Contains(_insertButtons.Item(i)) Then _insertButtons.RemoveAt(i)
                Next
                For Each ctl As Control In value
                    If Not _insertButtons.Contains(ctl) Then _insertButtons.Add(ctl)
                Next
            End If
        End Set
    End Property
    Private Function ShouldSerializeInsertButtons() As Boolean
        Return _insertButtons.Count > 0
    End Function
    Private Sub ResetInsertButtons()
        InsertButtons = Nothing
    End Sub

Я поместил редактор в zip-файл; скачать его можно здесь.

Как я упоминал ранее, это было просто быстрое и грязное решение, предназначенное только для внутреннего использования.Тем не менее, я был бы признателен за любые предложения по улучшению.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top