Exemple de propriété d'objet avec un petit plus dans la fenetre propriete (style ce que l'on trouve devant la propriete font

Soyez le premier à donner votre avis sur cette source.

Snippet vu 8 994 fois - Téléchargée 35 fois

Contenu du snippet

Voici un moyen d'afficher une propriete qui regroupe plusieurs valeurs, par exemple dans un Textbox vous avez une propriete font qui regroupe la taille de la font, le nom etc....

voici un code qui permet de faire ca avec ces propres objets...

Ce code est la traduction en VB.net du code C# de Arthenius --> http://www.csharpfr.com/code.aspx?ID=25912

Source / Exemple :


'VOICI LA CLASSE QUI DOIT DEFINIR MES PROPRIETES DEVANT APPARAITRE DANS LA FENETRE PROPRIETE AVEC LE PETIT PLUS...
    <TypeConverter(GetType(Mon_ensemble_de_propriete_Converter))> _
    Public Class Mon_ensemble_de_propriete
        Private _Nom As String
        Private _Prenom As String
        Public Property Nom() As String
            Get
                Return _Nom
            End Get
            Set(ByVal value As String)
                _Nom = value
            End Set
        End Property
        Public Property Prenom() As String
            Get
                Return _Prenom
            End Get
            Set(ByVal value As String)
                _Prenom = value
            End Set
        End Property
    End Class

    'ICI LE CONVERTER PERMETTANT D'AFFICHER LE PLUS DANS LA FENETRE PROPRIETE
    Public Class Mon_ensemble_de_propriete_Converter
        Inherits ExpandableObjectConverter

        Public Overrides Function CanConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal destinationType As System.Type) As Boolean

            If Not destinationType.GetType().Equals(New System.ComponentModel.Design.Serialization.InstanceDescriptor(Nothing, Nothing).GetType()) Then
                Return True
            End If

        End Function

        Public Overrides Function ConvertTo(ByVal context As System.ComponentModel.ITypeDescriptorContext, ByVal culture As System.Globalization.CultureInfo, ByVal value As Object, ByVal destinationType As System.Type) As Object
            Dim instancedescripteur As New System.ComponentModel.Design.Serialization.InstanceDescriptor(Nothing, Nothing)

            If Not destinationType.GetType() Is instancedescripteur.GetType() Then
                Return Me.ConvertTo(context, culture, value, destinationType)
            End If

            Dim ci As System.Reflection.ConstructorInfo = GetType(Mon_ensemble_de_propriete).GetConstructor(Nothing)
            Return New System.ComponentModel.Design.Serialization.InstanceDescriptor(ci, Nothing, False)

        End Function

    End Class

               'AU FINAL DANS MON OBJET J'AURAI UNE PROPRIETE DEFINIT COMME CA :
        Private Arthenius As New Mon_ensemble_de_propriete()
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
        Public Property Mais_qui_est_Arthenius() As Mon_ensemble_de_propriete
            Get
                Return Arthenius
            End Get
            Set(ByVal value As Mon_ensemble_de_propriete)
                Arthenius = Value
            End Set
        End Property

Conclusion :


Voila...maintenant vous aussi vous pourrez faire des propriétés "groupés" ca evitera a tout le monde de scroller pendant trois heures la fenetre des propriétés des objets...

Si vous avez des Interrogations des appréciations n'hesitez pas...POSTER :o)))

Ce code n'est pas de moi mais de Arthenius --> http://www.csharpfr.com/code.aspx?ID=25912

A voir également

Ajouter un commentaire

Commentaires

Messages postés
70
Date d'inscription
mercredi 24 avril 2002
Statut
Membre
Dernière intervention
17 septembre 2006

Bon, j'ai trouvé une solution pour mon problème de serialisation.
Je n'ai pas vraiment d'explication sur le pourquoi du comment et ça m'agace un peu.

Je vais garder cette solution pour le moment car c'est la seule que j'ai :-)
En fait, en reprenant l'exemple qu'on a dans ce source, je vais créer dans ma classe Mon_ensemble_de_propriete une variable défaut pour chaque variable

Private NomDefaut As String = ""
Private PrenomDefaut As String = ""

Je vire les attributs DefaultValue au dessus des propriétés et j'ajoute mes méthodes ShouldSerialize(Property) et Reset(Property) dans lesquels je vais tester mes valeurs par défaut.

-----------------------
Public Property Nom As String
Get
Return _Nom
End Get
Set(ByVal Value As String)
_Nom = Value
End Set

Private Function ShouldSerializeNom As Boolean
Return _Nom <> _NomDefaut
End Function

Private Sub ResetNom
_Nom = _NomDefaut
End Sub

'... Idem pour prénom
--------------------

Vous me direz, ça ne change pas grand chose.
Et bien voici la subtilité.

En implémentant ICloneable à la classe, on remarque que la méthode Clone est appelé au moment du design, lorsqu'on affecte la propriété.
Pourquoi ? je ne sais pas encore.

Voilà ce que j'ai fait pour le moment

'*** Clone de la classe
Public Function Clone() As Object _
Implements System.ICloneable.Clone

Me._NomDefaut = Me._Nom
Me._PrenomDefaut = Me._Prenom
Return Me.MemberwiseClone
End Function

Je m'en vais essayer de trouver une explication.
Cela fait quand même une semaine que je trime à trouver une solution et maintenant que j'en ai une, j'aimerais bien être sur que c'est fiable.

Si quelqu'un à une idée, je suis preneur...
Messages postés
70
Date d'inscription
mercredi 24 avril 2002
Statut
Membre
Dernière intervention
17 septembre 2006

Attention dans le code précédent dans la méthode ConvertTo, la dernière ligne est :

=> MyBase
Return MyBase.ConvertTo(context, culture, value, destinationType)

et non

=> Me
Return Me.ConvertTo(context, culture, value, destinationType)

qui provoque une boucle récursive infinie !!
Messages postés
70
Date d'inscription
mercredi 24 avril 2002
Statut
Membre
Dernière intervention
17 septembre 2006

Bonjour,
Comme je l'ai indiqué sur la source en c#, j'ai un problème de serialisation lorsqu'on hérite d'un écran sur lequel se trouve le control qui contient ce genre de propriété.
Je n'ai toujours pas trouvé de solution à mon problème

Cependant, je peux apporter ma contribution à ce source en ce qui concerne la classe Converter.
il y avait quelques erreurs ...

If Not destinationType.GetType().Equals(New System.ComponentModel.Design.Serialization.InstanceDescriptor(Nothing, Nothing).GetType()
=> destinationType est déjà un type
=> Inutile de créer une instance de InstanceDescriptor pour obtenir le type
GetType(InstanceDescriptor suffit)

Dim ci As System.Reflection.ConstructorInfo GetType(Mon_ensemble_de_propriete).GetConstructor(Nothing)
> Dans getConstructor, il faut passer une liste de type, même si c'est vide
(New Type(){} = Tableau de type vide)

Return New System.ComponentModel.Design.Serialization.InstanceDescriptor(ci, Nothing, False)
=> Idem dans instance descriptor
(New Object(){} Tableau d'objet vide)
> Pourquoi False pour le dernier argument ?

N.B:
Si on a un constructeur avec en paramètre Nom et Prenom, on peut appeler ce constructeur

Dim ci As System.Reflection.ConstructorInfo = GetType(Mon_ensemble_de_propriete).GetConstructor(New Type(){GetType(String), GetType(String)})

With CType(value, Mon_ensemble_de_propriete)
Return New System.ComponentModel.Design.Serialization.InstanceDescriptor(ci, New Object(){.Nom, .Prenom)
End With

Voilà la classe corrigé :

Public Class Mon_ensemble_de_proprieteConverter
Inherits ExpandableObjectConverter

Public Overloads Overrides Function CanConvertTo( _
ByVal context As System.ComponentModel.ITypeDescriptorContext, _
ByVal destinationType As System.Type _
) As Boolean

If destinationType Is GetType(System.ComponentModel.Design.Serialization.InstanceDescriptor) Then
Return True
End If

Return MyBase.CanConvertTo(context, destinationType)
End Function

Public Overloads Overrides Function ConvertTo( _
ByVal context As System.ComponentModel.ITypeDescriptorContext, _
ByVal culture As System.Globalization.CultureInfo, _
ByVal value As Object, _
ByVal destinationType As System.Type _
) As Object

If _
destinationType Is GetType(String) AndAlso _
TypeOf value Is Mon_ensemble_de_propriete Then

' Permet d'affiche blanc sur le propertyGRid
Return ""
End If

If _
destinationType Is GetType(System.ComponentModel.Design.Serialization.InstanceDescriptor) AndAlso _
TypeOf value Is Mon_ensemble_de_propriete Then

Dim ci As System.Reflection.ConstructorInfo = GetType(Mon_ensemble_de_propriete).GetConstructor(New Type() {})
Return New System.ComponentModel.Design.Serialization.InstanceDescriptor(ci, New Object() {})
End If

Return Me.ConvertTo(context, culture, value, destinationType)
End Function
End Class
Messages postés
2
Date d'inscription
jeudi 17 août 2006
Statut
Membre
Dernière intervention
1 décembre 2007

Et maintenant la totale avec des valeurs par défaut, y compris pour des types un peu plus compliqués comme les couleurs et les polices de caractères.
Bon courage à tous.

Imports System.ComponentModel


Public Class UserControl1

Private Arthenius As New Mon_ensemble_de_propriete()

<DesignerSerializationVisibility(DesignerSerializationVisibility.Content)> _
Public Property Mais_qui_est_Arthenius() As Mon_ensemble_de_propriete
Get
Return Arthenius
End Get
Set(ByVal value As Mon_ensemble_de_propriete)
Arthenius = value
End Set
End Property

End Class

' VOICI LA CLASSE QUI DOIT DEFINIR MES PROPRIETES DEVANT APPARAITRE DANS LA FENETRE PROPRIETE
' AVEC LE PETIT PLUS...

<TypeConverter(GetType(ExpandableObjectConverter))> _
Public Class Mon_ensemble_de_propriete
'
' objets privés initialisés avec les valeurs par défaut
'
Private _Nom As String = "Dupont"
Private _Prenom As String = "Robert"
Private _Couleur As Color = Color.Red
Private _Police As Font = New Font("Microsoft Sans Serif", 8.25!, FontStyle.Bold, GraphicsUnit.Point, CType(0, Byte))
'
' objet privé pour la comparaison par le designer dans ShouldSerialize...
'
Private _PoliceParDefaut As Font = New Font("Microsoft Sans Serif", 8.25!, FontStyle.Bold, GraphicsUnit.Point, CType(0, Byte))
'
' propriétés
'
' <summary> sera rangé dans le fichier XML créé avec la DLL
' un développeur ayant uniquement la DLL et le fichier XML aura à l'écran la description de la propriété
' dès qu'il entrera dans son code objet.propriété
'
' <Description> pour que la description s'affiche dans la fenêtre des propriétés en mode Design
'
' <DefaultValue> pour permettre au Designer de faire apparaître la valeur de la propriété en caractères normaux
' lorsque la valeur est celle par défaut
' pour les autres valeurs que la valeur par défaut, la valeur est affichée en gras dans la fenêtre des propriétés
' Ceci ne s'applique qu'aux types simples : string , boolean , integer , etc...
' Pour les objets compliqués commeles couleurs et les polices de caractères <DefaultValue> ne marche pas
' et doir être remplacé par une fonction ShouldSerialize, voir plus loin.


''' <summary>
''' Nom de l'individu
''' (Valeur par défaut : Dupont)
''' </summary>
<DefaultValue("Dupont")> _
<Description("Nom de l'individu")> _
Public Property Nom() As String
Get
Return _Nom
End Get
Set(ByVal value As String)
_Nom = value
End Set
End Property


''' <summary>
''' Prénom de l'individu
''' (Valeur par défaut : Robert)
''' </summary>
<DefaultValue("Robert")> _
<Description("Prénom de l'individu")> _
Public Property Prenom() As String
Get
Return _Prenom
End Get
Set(ByVal value As String)
_Prenom = value
End Set
End Property


''' <summary>
''' Couleur préférée
''' (Valeur par défaut : Color.Red)
''' </summary>
<Description("Couleur préférée")> _
Public Property Couleur() As Color
Get
Return _Couleur
End Get
Set(ByVal value As Color)
_Couleur = value
End Set
End Property

Private Function ShouldSerializeCouleur() As Boolean
Return Me.Couleur <> Color.Red
End Function


''' <summary>
''' Police préférée
''' (Valeur par défaut : Microsoft Sans Serif 8,25pt Bold)
''' </summary>
<Description("Police préférée")> _
Public Property Police() As Font
Get
Return _Police
End Get
Set(ByVal value As Font)
_Police = value
End Set
End Property

Private Function ShouldSerializePolice() As Boolean
Return Not Me.Police.Equals(_PoliceParDefaut)
End Function

End Class
Messages postés
115
Date d'inscription
samedi 15 février 2003
Statut
Membre
Dernière intervention
18 mai 2008

Ok j'ai trouvé ! ouf !

l'auteur en code C# a fait quelque modifications, aller effectivement voir sur http://www.csharpfr.com/code.aspx?ID=25912

En fait vous devez laisser tomber la classe Mon_ensemble_de_propriete_Converter
C'est elle la source du problème.
Pour définir le type de Mon_ensemble_de_propriete, il suffit directement de convertir le type ExpandableObjectConverter : <TypeConverter(GetType(ExpandableObjectConverter
))>

et là plus de soucis !

A+
Afficher les 9 commentaires

Vous n'êtes pas encore membre ?

inscrivez-vous, c'est gratuit et ça prend moins d'une minute !

Les membres obtiennent plus de réponses que les utilisateurs anonymes.

Le fait d'être membre vous permet d'avoir un suivi détaillé de vos demandes et codes sources.

Le fait d'être membre vous permet d'avoir des options supplémentaires.