Question

Je voudrais ajouter une propriété qui représente une collection de contrôles à un composant et un éditeur de collection avec laquelle je peux facilement sélectionner les commandes qui appartiennent à la collection. VS fait presque ce que je veux automatiquement le code suivant:

    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

Je reçois la valeur par défaut CollectionEditor, peut ajouter et supprimer des contrôles, et la collection est sérialisé.

Le problème est que je ne veux pas ajouter nouveaux commandes, je veux sélectionner plusieurs contrôles des autres commandes disponibles sur le formulaire. Est-il un moyen facile / standard pour ce faire, ou devrai-je écrire mon propre éditeur de collection et exécuter à travers la collection de contrôles?

Bien qu'il y ait beaucoup de matériel sur les éditeurs de collecte (de UITypeEditors) et d'autres sujets à temps la conception, je ne l'ai pas été en mesure de trouver des liens montrant ce comportement exact, de sorte que toute aide est appréciée.

Était-ce utile?

La solution

OK, donc dans le même temps j'ai déjeuné et écrit l'éditeur moi-même. Était-ce pas un grand effort. Je serais heureux de partager, si elle aide.

Edit: Solution Résumé

J'ai écrit un éditeur (voir capture d'écran) qui fait une liste récursive tous les contrôles sur le formulaire dans une vue arborescente. Si les contrôles ont leurs propriétés de texte ou l'image définir le texte / image est affichée. L'utilisateur peut sélectionner plusieurs contrôles avec des cases à cocher et même de filtrer la liste des contrôles d'affichage uniquement de certains types.

(je dois admettre, cependant, que depuis cet éditeur était uniquement destiné à un usage interne, je ne l'ai pas pris la peine de vérifier la propriété d'image génériquement, je viens de gérer un couple de types de contrôle bien connus.)

Le code sous la forme de l'éditeur est vraiment juste pour l'interface utilisateur, responsable de remplir l'arbre, la définition des contrôles sur la liste des contrôles pré-sélectionnés et en retournant la liste des contrôles sélectionnés lorsque l'utilisateur ferme le formulaire en cliquant sur OK.

Ensuite, nous avons une classe qui implémente UITypeEditor, que j'ai appelé FormControlSelectionEditor. Cette classe est affectée aux propriétés que nous voulons utiliser l'éditeur pour utiliser l'attribut [Editor]. Il ne fait pas beaucoup plus que de créer une nouvelle instance de la forme en cas de besoin et l'afficher comme une boîte de dialogue modale.

Ensuite, il y a les propriétés elles-mêmes, qui sont de type System.Collections.ObjectModel.ObservableCollection (de contrôle). J'ai choisi ObservableCollection parce que je dois réagir aux changements aux listes à l'exécution ainsi, mais d'autres listes seraient tout aussi bien avec une adaptation mineure.

Une chose que je découvre est que je devais écrire mes propriétés et éditeur de telle sorte qu'ils utilisent des copies des listes de contrôles. En d'autres termes, le code UITypeEditor fait une copie de la liste stockée dans la propriété et il passe à la forme de l'éditeur (pour le réglage des contrôles lorsque le formulaire est ouvert), et lorsque le formulaire est fermé, je restaurez la liste de soutien de la propriété et copier sur chaque commande dans la liste renvoyée de l'éditeur. Je trouve que sinon j'eu des problèmes avec la sérialisation dans le fichier .designer. Je ne crois pas qu'il doit être de cette façon; Je pense qu'il est plus probable une erreur de ma part.

Code pour une propriété typique:

    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

J'ai mis l'éditeur dans un fichier zip; télécharger ici .

Comme je l'ai mentionné précédemment, c'était juste une solution rapide et sale destinée à un usage interne. Malgré tout, je vous remercie des suggestions d'amélioration.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top