EXEMPLE DE PROPRIÉTÉ D'OBJET AVEC UN PETIT PLUS DANS LA FENETRE PROPRIETE (STYLE

Signaler
Messages postés
115
Date d'inscription
jeudi 11 octobre 2001
Statut
Membre
Dernière intervention
15 octobre 2012
-
Messages postés
70
Date d'inscription
mercredi 24 avril 2002
Statut
Membre
Dernière intervention
17 septembre 2006
-
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
Afficher les 9 commentaires