IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

VB.NET Discussion :

VB.NET Modifier un type personnalisé dans l'éditeur de propriétés


Sujet :

VB.NET

  1. #1
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2013
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2013
    Messages : 22
    Points : 22
    Points
    22
    Par défaut VB.NET Modifier un type personnalisé dans l'éditeur de propriétés
    Bonjour,

    Mon contrôle UserControl a une propriété d'un type personnalisé. Ce type est relativement similaire aux types Size ou Point, par exemple : son constructeur prend deux paramètres et il contient deux propriétés publiques.
    J'ai réussi à l'afficher dans la fenêtre Propriétés (en bas à droite lorsqu'on utilise l'éditeur visuel).
    En revanche, je ne parviens pas à :
    - modifier les propriétés de mon objet (les propriétés sont modifiées jusqu'à ce qu'on ferme l'éditeur, mais le changement n'est pas sauvegardé dans le fichier Designer.vb),
    - définir une valeur par défaut reconnue par l'éditeur.

    EDIT : Après redémarrage de Visual Studio, ce deuxième problème semble résolu et la valeur par défaut est prise en compte.

    Voici mon code :

    MonObjetConverter.vb
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    Option Explicit On
    Option Strict On
     
    Imports System
    Imports System.ComponentModel
    Imports System.Globalization
    Imports System.Drawing
     
    Friend Class MonObjetConverter
        Inherits ExpandableObjectConverter
     
        ' Overrides the CanConvertFrom method of TypeConverter.
        ' The ITypeDescriptorContext interface provides the context for the
        ' conversion. Typically, this interface is used at design time to 
        ' provide information about the design-time container.
        Public Overloads Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean
            If sourceType Is GetType(String) Then
                Return True
            End If
            Return MyBase.CanConvertFrom(context, sourceType)
        End Function
     
        ' Overrides the ConvertFrom method of TypeConverter.
        Public Overloads Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object
            If TypeOf value Is String Then
                Dim v As String() = CStr(value).Split(New String() {"; "}, StringSplitOptions.RemoveEmptyEntries)
                Return New MonObjet(Integer.Parse(v(0)), Integer.Parse(v(1)))
            End If
            Return MyBase.ConvertFrom(context, culture, value)
        End Function
     
        ' Overrides the ConvertTo method of TypeConverter.
        Public Overloads Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As CultureInfo, value As Object, destinationType As Type) As Object
            If destinationType Is GetType(String) Then
                Return CType(value, MonObjet).Propriété1 & "; " & CType(value, MonObjet).Propriété2
            End If
            Return MyBase.ConvertTo(context, culture, value, destinationType)
        End Function
    End Class
    MonObjet.vb
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    Imports System.ComponentModel
     
    <TypeConverter(GetType(MonObjetConverter))>
    Public Structure MonObjet
     
        Public Sub New(ByVal p1 As Integer, ByVal p2 As Integer)
           Propriété1 = p1
           Propriété2 = p2
        End Sub
     
        <DefaultValue(1)>
        Public Property Propriété1 As Integer
     
        <DefaultValue(3)>
        Public Property Propriété2 As Integer
     
    End Structure
    MonControle.vb
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Imports System.ComponentModel
     
    Public Class MonControle
     
    [...]
     
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden),
        DefaultValue(GetType(MonObjet), "1; 3")>
        Public Property PropriétéMonObjet As New MonObjet(1, 3)
     
    [...]
     
    End Class
    L'éditeur affiche la valeur 1; 3 en gras (comme si la valeur avait été modifiée) - mais les propriétés de l'objet ne sont pas en gras.
    Lorsque j'appuie sur Réinitialiser, il affiche 0; 0 (toujours en gras).


    Lorsque je ferme et que je rouvre l'éditeur, la valeur est à nouveau à 1; 3.

    Nom : Capture.PNG
Affichages : 238
Taille : 6,2 Ko

    Je sais qu'on ne peut pas modifier directement les sous-propriétés de cette manière :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    MonObjet.PropriétéMonObjet.Propriété1 = 5
    On obtient l'erreur : Cette expression est une valeur et ne peut donc pas être la cible d'une assignation
    D'ailleurs, je ne sais pas pourquoi, car les propriétés ne sont pas en lecture seule.

    Mais l'éditeur est capable de modifier la taille et la position des fenêtres, par exemple. Pour cela, il crée un nouvel objet qui prend les paramètres désirés.

    Form1.Designer.vb
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    Me.Size = New System.Drawing.Size(100, 200)
    Connaîtriez-vous un moyen de réaliser ce que je souhaite ?

    Cordialement,
    E__Man.

  2. #2
    Expert éminent sénior Avatar de Pol63
    Homme Profil pro
    .NET / SQL SERVER
    Inscrit en
    Avril 2007
    Messages
    14 153
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Puy de Dôme (Auvergne)

    Informations professionnelles :
    Activité : .NET / SQL SERVER

    Informations forums :
    Inscription : Avril 2007
    Messages : 14 153
    Points : 25 071
    Points
    25 071
    Par défaut
    typeconverter + différence entre classe et structure
    Cours complets, tutos et autres FAQ ici : C# - VB.NET

  3. #3
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2013
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2013
    Messages : 22
    Points : 22
    Points
    22
    Par défaut
    Je ne comprends pas votre réponse :

    J'ai déjà un TypeConverter, comme indiqué dans mon message.

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Friend Class MonObjetConverter
        Inherits ExpandableObjectConverter
    Et il n'y a aucun changement si je remplace Structure par Class.
    D'ailleurs, le type System.Drawing.Size est une structure, comme mon type.

  4. #4
    Expert confirmé
    Inscrit en
    Avril 2008
    Messages
    2 564
    Détails du profil
    Informations personnelles :
    Âge : 64

    Informations forums :
    Inscription : Avril 2008
    Messages : 2 564
    Points : 4 441
    Points
    4 441
    Par défaut
    bonjour
    Et il n'y a aucun changement si je remplace Structure par Class.
    D'ailleurs, le type System.Drawing.Size est une structure, comme mon type.
    il te faut:
    1/ une méthode CanConvertTo qui renvoie un InstanceDescriptor pour le destinationType

    2/ revoir ta méthode ConvertTo qui doit renvoyer un Ctor

    3/ rajouter les overrides des 2 méthodes suivantes (explication voir commentaires di code exemple ci-joint):
    -GetCreateInstanceSupported
    -CreateInstance
    4/ mettre le tout: UserCpntrol ,Structure Point d'exemple et son convertisseur de type dans un projet ControlLibrary1

    bref voici le code exemple complet :
    1/ ControlLibrary1
    code du structure Point
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
     
    Imports System.ComponentModel
    <TypeConverter(GetType(PointConverter))>
    Public Structure Point
     
        Public Sub New(ByVal x1 As Integer, ByVal y1 As Integer)
            X = x1
            Y = y1
        End Sub
     
        <DefaultValue(1)>
        Public Property X As Integer
        <DefaultValue(3)>
        Public Property Y As Integer
    End Structure
    code de son converter
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
     
     
    Option Explicit On
    Option Strict On
     
    Imports System
    Imports System.ComponentModel
    Imports System.Globalization
    Imports System.Drawing
    Imports System.ComponentModel.Design.Serialization
    Imports System.Reflection
     
    Public Class PointConverter
        Inherits ExpandableObjectConverter
     
        ' Overrides the CanConvertFrom method of TypeConverter.
        '  The ITypeDescriptorContext interface provides the context for the
        ' conversion.  Typically, this interface is used at design time to 
        ' provide information about the design-time container.  
        Public Overloads Overrides Function CanConvertFrom(context As ITypeDescriptorContext, sourceType As Type) As Boolean
            If sourceType Is GetType(String) Then
                Return True
            End If
            Return MyBase.CanConvertFrom(context, sourceType)
        End Function
        Public Overrides Function CanConvertTo(context As System.ComponentModel.ITypeDescriptorContext, destinationType As System.Type) As Boolean
            If destinationType Is GetType(InstanceDescriptor) Then
                Return True
            End If
            Return MyBase.CanConvertTo(context, destinationType)
        End Function
        ' Overrides the ConvertFrom method of TypeConverter.  
        Public Overloads Overrides Function ConvertFrom(context As ITypeDescriptorContext, culture As CultureInfo, value As Object) As Object
            ' If converting from a string
            If TypeOf value Is String Then
                Dim strValue As String = CType(value, String)
                If strValue Is Nothing Then Return Nothing
                strValue = strValue.Trim()
     
     
                Dim v As String() =
                CStr(value).Split(New String() {"; "}, StringSplitOptions.RemoveEmptyEntries)
                Dim intConverter As TypeConverter = TypeDescriptor.GetConverter(GetType(Integer))
                Dim value1 As Integer = CType(intConverter.ConvertFromString(context, culture, v(0)), Integer)
                Dim value2 As Integer = CType(intConverter.ConvertFromString(context, culture, v(1)), Integer)
                Return New Point(value1, value2)
            End If
            Return MyBase.ConvertFrom(context, culture, value)
        End Function
     
        ' Overrides the ConvertTo method of TypeConverter.  
        Public Overloads Overrides Function ConvertTo(context As ITypeDescriptorContext, culture As CultureInfo, value As Object, destinationType As Type) As Object
            If destinationType Is Nothing Then Throw New ArgumentNullException("destinationType")
            If TypeOf value Is Point Then
                If destinationType Is GetType(String) Then
                    Return CType(value, Point).X & "; " & CType(value, Point).Y
     
                Else ' Convert to InstanceDescriptor
                    If destinationType Is GetType(InstanceDescriptor) Then
                        Dim thePoint As Point = CType(value, Point)
     
                        Dim properties(1) As Object
                        Dim types(1) As Type
                        ' propX
                        types(0) = GetType(Integer)
                        properties(0) = thePoint.X
                        ' propB
                        types(1) = GetType(Integer)
                        properties(1) = thePoint.Y
                        ' Build constructor
                        Dim ctor As ConstructorInfo = GetType(Point).GetConstructor(types)
                        Return New InstanceDescriptor(ctor, properties)
                    End If
                End If
            End If
            Return MyBase.ConvertTo(context, culture, value, destinationType)
        End Function
     
        'sans ces 2 methodes  on ne voit pas les valeurs devant ThePoint dans le concepteur
        ' quand X & Y changent 
        ' Role en catimini : elles mettent à jour l' instance Point en fonction des nouvelles valeurs
        Public Overloads Overrides Function GetCreateInstanceSupported(
                                                                      context As ITypeDescriptorContext) As Boolean
     
            ' Always force a new instance
            Return True
        End Function
     
        Public Overloads Overrides Function CreateInstance(
                                                          context As ITypeDescriptorContext,
                                                          propertyValues As IDictionary) As Object
     
            ' Use the dictionary to create a new instance
            Return New Point(CType(propertyValues("X"), Integer), CType(propertyValues("Y"), Integer))
        End Function
     
    End Class
    code du Usercontrol
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
     
    Imports System.ComponentModel
     
    Public Class ControlPoint
        Inherits UserControl
        Public Sub New()
     
            ' Cet appel est requis par le concepteur.
            InitializeComponent()
     
            ' Ajoutez une initialisation quelconque après l'appel InitializeComponent().
            ThePoint = New Point(1, 3)
        End Sub
     
        <DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)>
        <DefaultValue(GetType(Point), "1;3")>
        Public Property ThePoint As Point
     
    End Class
    Tu pourras contempler le code généré par le VS Designer de l'initialisation du structure Point dans le fichier Form1.Designer.vb...!!!
    Tu pourras aussi dans le Concepteur Pointer sur la prop ThePoint & Click droit voir apparaître un Menu avec la commande Réinitialiser qui mettra X =1 & T=3


    bon code...

  5. #5
    Membre à l'essai
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Août 2013
    Messages
    22
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Août 2013
    Messages : 22
    Points : 22
    Points
    22
    Par défaut
    Merci beaucoup, ça fonctionne !
    Le seul problème est qu'il faut redémarrer Visual Studio chaque fois que l'on édite la structure Point.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [AC-2013] Comment modifier un menu personnalisé dans Access 2013
    Par elgordopresto dans le forum Access
    Réponses: 1
    Dernier message: 30/04/2018, 19h19
  2. Réponses: 6
    Dernier message: 03/05/2012, 14h24
  3. Modifier un type User_Data dans le Simple_Handler
    Par Invité dans le forum GTK+ avec C & C++
    Réponses: 4
    Dernier message: 16/11/2010, 16h15
  4. Réponses: 3
    Dernier message: 13/10/2009, 12h32
  5. [VB.Net] Créer un type personnalisé
    Par andlio dans le forum VB.NET
    Réponses: 5
    Dernier message: 20/07/2007, 16h14

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo