Pregunta

Me gustaría añadir una propiedad que representa una colección de controles a un componente y un editor de la colección con la que puedo seleccionar fácilmente los controles que pertenecen a la colección. VS hace casi lo que quiero de forma automática con el siguiente código:

    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

Me da la CollectionEditor por defecto, puede añadir y eliminar los controles, y la colección es de serie.

El problema es que no quiero añadir nuevos controles, quiero seleccionar varios controles de los otros controles disponibles en el formulario. ¿Hay alguna forma fácil / estándar de hacer esto, o voy a tener que escribir mi propio editor de la colección y ejecutar a través de la colección de controles?

A pesar de que hay un montón de material sobre editores de la colección (UITypeEditors) y otros temas en tiempo de diseño, no he podido encontrar ningún enlace que demuestran este comportamiento exacto, por lo que cualquier ayuda se agradece.

¿Fue útil?

Solución

Aceptar, por lo que en la media hora que he tenido el almuerzo y escrito el editor de mí mismo. No fue un gran esfuerzo. Yo estaría encantado de compartir, si ayuda.

Editar: Solución Resumen

escribí un editor (ver captura de pantalla), que recurrentemente se enumeran todos los controles que se encuentran en el formulario en una vista de árbol. Si los controles tienen sus propiedades de texto o imagen set se muestra el texto / imagen. El usuario puede seleccionar varios controles con casillas de verificación e incluso filtrar la lista para sólo los controles de visualización de ciertos tipos.

(Debo admitir, sin embargo, que desde este editor sólo estaba destinado a uso interno, no se molestan en comprobar la propiedad de imagen de forma genérica, que se encarga solamente de un par de tipos de control conocidos.)

texto alternativo

El código en la forma editor es realmente sólo para la interfaz de usuario, responsable de llenar el árbol, el establecimiento de los controles en la lista de controles preseleccionados y devolver la lista de controles seleccionados cuando el usuario cierra el formulario con OK.

A continuación, tenemos una clase que implementa UITypeEditor, que llamé FormControlSelectionEditor. Esta clase se asigna a las propiedades que queremos usar el editor para usar el atributo [Editor]. No hace mucho más que crear una nueva instancia del formulario cuando sea necesario y mostrarlo como un cuadro de diálogo modal.

Luego están los propios propiedades, que son de tipo System.Collections.ObjectModel.ObservableCollection (Of Control). Elegí ObservableCollection porque necesito para reaccionar a cambios en las listas en tiempo de ejecución, así, pero otras listas haría igual de bien con una mínima adaptación.

Una cosa que descubrí es que tuve que escribir mis propiedades y editor de tal manera que ellos usan copias de las listas de controles. En otras palabras, el código UITypeEditor hace una copia de la lista almacenada en la propiedad y la pasa a la forma editor (para ajustar los controles cuando se abre el formulario), y cuando se cierra el formulario, I Borrar lista el respaldo de la propiedad y copiar cada control en la lista devuelta desde el editor. Me encontré con que de otra manera he tenido problemas con la serialización en el archivo .designer. No creemos que tiene que ser así; Creo que es más probable un error de mi parte.

Código para una propiedad típica:

    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

He puesto el editor en un archivo zip; descargarlo aquí .

Como he mencionado antes, esto era sólo una solución rápida y sucia destinada a uso interno. De todos modos, le agradecería cualquier sugerencia de mejora.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top