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 :

usercontrol : obliger une propriété à être d'un type qui hérite d'un type de base bien précis


Sujet :

VB.NET

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut usercontrol : obliger une propriété à être d'un type qui hérite d'un type de base bien précis
    Bonjour,

    Je m'amuse actuellement à créer un contrôle pour afficher un diagramme de Gantt (ceux que l'on peut trouver sur le net en libre/payant ne correspondent pas bien à mon besoin).

    Dans le code de mon usercontrol, j'ai donc une propriété que j'ai nommée DataSource qui sera chargée de recevoir les données à afficher dans le diagramme (aussi bien dans le DataGridView de gauche que la PictureBox de droite (cf. image en pièce jointe).

    Le hic, c'est que pour afficher les barres dans ma PictoreBox, j'ai besoin d'informations spécifiques.

    Pour donner un exemple concret, voici un modèle simple de classes :
    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
    Public Class Employee
        Public Property Name As String
        Public Property Ranges As List(Of Range)
        Public Sub New(name As String)
            Me.Name = name
            Ranges = New List(Of Range)
        End Sub
        Public Sub AddRange(debut As Decimal, fin As Decimal, type As Range.TypeRange)
            ...
        End Sub
        Public Function GetRangeSurrounding(time As Decimal) As Range
            ...
        End Function
        Private Sub AddSimplifiedRange(debut As Decimal, fin As Decimal, type As Range.TypeRange)
            ...
        End Sub
        Private Sub SimplifyRange()
            ...
        End Sub
        Private Function GetRangeById(id As Integer) As Range
            ...
        End Function
    End Class
    Public Class Range
        Public Property Id As Integer
        Public Property Debut As Decimal
        Public Property Fin As Decimal
        Public Property Type As TypeRange
        Public Property Text As String
     
        Public Sub New(id As Integer, debut As Decimal, fin As Decimal, type As TypeRange)
            Me.Id = id
            Me.Debut = debut
            Me.Fin = fin
            Me.Type = type
        End Sub
    End Class
    Bon, là j'avais le test avec des employés donc la classe s'appelle Employee mais l'idée est là. Pour que mon contrôle fonctionne, il faut que l'objet passé à ma propriété DataSource hérite de cette classe Employee (qui sera bien sûr renommée de manière appropriée).

    Ma question est donc : Comment définir que, pour une propriété d'une classe, son type DOIT hériter d'un type précis ?
    Images attachées Images attachées  

  2. #2
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 436
    Par défaut
    Peut être comme avec les génériques et le where.

    Exemple pour une méthode :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    public void SetDateSource(T dataSource) where T : ITypeObjetCommun, new()
    {
     
    }
    Je te montre un exemple de code que j'ai :

    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
     
    public IEnumerable<T> GetAll<T>() where T : ICategorie, new()
    		{
    			IEnumerable<T> resultat = null;
     
    			using (var edmx = new EDMXContainer())
    			{
    				var listeObj = edmx.CATEGORIES;
    				var liste = new List<T>();
     
    				if (listeObj.Count() > 0)
    				{
    					foreach (var element in listeObj)
    					{
    						liste.Add(new T() { Id = element.Id, Code = element.Code, Libelle = element.Libelle, Description = element.Description, Image = element.Image });
    					}
    				}
    				if (liste.Count() > 0) resultat = liste;
     
    			}
     
    			return resultat;
    		}
     
    //appel :
     
    var all = (List<CategorieDTO>)bll.GetAll<CategorieDTO>();
    Le new permet d'utiliser le type passé dans la fonction en type de retour.

    Tu peux définir une interface ITypeObjetCommun qui regroupe les infos obligatoires puis étendre les models qui l'implémente en fonction des besoins de chacun.

    (ps : ce n'est qu'une piste je n'ai pas beaucoup réfléchi au problème car je suis en pleine digestion et sur un dév un peu casse bonbon ^^)

  3. #3
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Billets dans le blog
    3
    Par défaut
    Tu peux mettre Employee comme étant le type de la propriété.

    Ainsi si tu as une classe EmployeeExtended qui hérite de Employee, tu pourras la passer à ta propriété...
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  4. #4
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    @Kikuts : Merci pour l'exemple. Je ne parle pas le C#. Du coup, je l'ai passé dans un traducteur et j'ai pas tout compris ^^.

    @DotNetMatt (encore toi ? :p) : J'y avais songé. Ca se fait ce genre de choses ? J'ai pas osé car j'me suis dit que c'était une méthode de bourrin .


    Question corollaire :
    Disons que j'applique la solution de DotNetMatt et que je renomme Employee en Source histoire d'être plus générique. Toujours pour être plus générique, je retire la propriété Name. Quand dans le programme qui utilisera mon contrôle, le dev affectera à DataSource un objet qui hérite de Source, comment dois-je faire pour connaître les propriétés qui existe en plus de Ranges ? Le mot réflexion me vient à l'esprit mais je ne l'ai encore jamais utilisée. Suis-je sur la bonne voie ?

  5. #5
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Billets dans le blog
    3
    Par défaut
    Citation Envoyé par Kropernic Voir le message
    @DotNetMatt (encore toi ? :p) : J'y avais songé. Ca se fait ce genre de choses ? J'ai pas osé car j'me suis dit que c'était une méthode de bourrin .
    Oui encore moi Et oui ça se fait, c'est le principe de l'héritage Il y a d'autres moyens comme l'a dit Kikuts, comme par exemple en utilisant une interface, ou encore en passant par une classe abstraite.

    Citation Envoyé par Kropernic Voir le message
    Question corollaire :
    Disons que j'applique la solution de DotNetMatt et que je renomme Employee en Source histoire d'être plus générique. Toujours pour être plus générique, je retire la propriété Name. Quand dans le programme qui utilisera mon contrôle, le dev affectera à DataSource un objet qui hérite de Source, comment dois-je faire pour connaître les propriétés qui existe en plus de Ranges ? Le mot réflexion me vient à l'esprit mais je ne l'ai encore jamais utilisée. Suis-je sur la bonne voie ?
    La réflexion peut être utilisée dans ce cas, mais c'est surtout par un cast que tu pourras retrouver l'objet original. Un exemple :
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    Dim sourceExt = New SourceExtended()    ' SourceExtended hérite de Source
    Dim dc = New DummyClass()    ' DummyClass est une classe "bidon"...
    dc.Source = sourceExt    ' La propriété Source est de type Source...
     
    sourceExt = DirectCast(dc.Source, SourceExtended)    ' Avec un cast, on retrouve notre type initial (SourceExtended)
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

  6. #6
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Euh oui mais dans mon contrôle, je n'ai aucune idée de que le dev qui l'utilisera me donnera comme type (qui devra donc hériter de Source).

    L'idée est de pouvoir passer toutes les propriétés de l'objet au DGV et de garder la propriété Range pour la partie d'affichage des barres du diagramme.

    N.B. : En fait, la propriété DataSource doit être de type List(Of Source). Sinon, il n'y aura jamais qu'une seule ligne ^^

  7. #7
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 436
    Par défaut
    Citation Envoyé par Kropernic Voir le message
    @DotNetMatt (encore toi ? :p)
    Il est partout ! En tout cas, il répond souvent présent quand j'ai un problème ! Mathieu est un mec en or

    Si jamais tu veux je te mettrais le code en VB (à la base je l'avais fait en VB puis en c# pour un projet perso)

  8. #8
    Membre expérimenté
    Avatar de Kropernic
    Homme Profil pro
    Analyste / Programmeur / DBA
    Inscrit en
    Juillet 2006
    Messages
    3 932
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : Belgique

    Informations professionnelles :
    Activité : Analyste / Programmeur / DBA
    Secteur : Distribution

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Par défaut
    Citation Envoyé par Kikuts Voir le message
    Il est partout ! En tout cas, il répond souvent présent quand j'ai un problème ! Mathieu est un mec en or

    Si jamais tu veux je te mettrais le code en VB (à la base je l'avais fait en VB puis en c# pour un projet perso)
    Oui, il est souvent là pour moi aussi. On a déjà quelques conversations sur des sujets forts intéressants.

    Pour le code, pas la peine. Je l'avais fait traduire sur developperfusion.com et je comprenais quand même pas ^^. Il y a plein de notion avec lesquelles je ne suis pas encore à l'aise et les génériques en font partie.

  9. #9
    Membre éclairé
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Novembre 2006
    Messages
    436
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 38
    Localisation : France, Hauts de Seine (Île de France)

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

    Informations forums :
    Inscription : Novembre 2006
    Messages : 436
    Par défaut
    Je ne suis toujours pas à l'aise avec alors que j'ai utilisé ce principe sur tout un projet xD

    Donc je te comprend faudrait que je trouve un livre bien complet là dessus un de ces 4 car depuis que je code, je crois que c'est un des trucs qui m'a fait le plus halluciner tant c'est puissant et permet de faire des choses incroyables !

  10. #10
    Modérateur
    Avatar de DotNetMatt
    Homme Profil pro
    CTO
    Inscrit en
    Février 2010
    Messages
    3 611
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 37
    Localisation : Etats-Unis

    Informations professionnelles :
    Activité : CTO
    Secteur : Finance

    Informations forums :
    Inscription : Février 2010
    Messages : 3 611
    Billets dans le blog
    3
    Par défaut
    Merci les gars J'essaie de faire du mieux possible

    Citation Envoyé par Kropernic
    Euh oui mais dans mon contrôle, je n'ai aucune idée de que le dev qui l'utilisera me donnera comme type (qui devra donc hériter de Source).
    C'est justement le principe : peu importe ce que le dev va te passer, l'important c'est qu'il hérite de Source. Je pense qu'il faut poser clairement le code...

    La classe Source, qui est la classe de base dont les autres vont hériter :
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Public Class Source
    	Public Property Id() As Integer
    		Get
    			Return m_Id
    		End Get
    		Set
    			m_Id = Value
    		End Set
    	End Property
    	Private m_Id As Integer
    End Class

    La classe SourceExtended, qui hérite de Source :
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Public Class SourceExtended
    	Inherits Source
    	Public Property ExtendedObject() As Object
    		Get
    			Return m_ExtendedObject
    		End Get
    		Set
    			m_ExtendedObject = Value
    		End Set
    	End Property
    	Private m_ExtendedObject As Object
    End Class

    La classe SourceFiltered, qui hérite aussi de Source :
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    Public Class SourceFiltered
    	Inherits Source
    	Public Property FilteredObject() As Object
    		Get
    			Return m_FilteredObject
    		End Get
    		Set
    			m_FilteredObject = Value
    		End Set
    	End Property
    	Private m_FilteredObject As Object
    End Class
    Ok, maintenant on va supposer que le développeur initialise un objet de type SourceFiltered :
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Dim sf = New SourceFiltered()
    sf.Id = 1
    sf.FilteredObject = New Object() {1, 2, 3}
    Pour le recevoir, j'ai deux options. La première c'est de recevoir on objet de type SourceFiltered :
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Public Class Control
    	Public Property DataSource() As SourceFiltered
    		Get
    			Return m_DataSource
    		End Get
    		Set
    			m_DataSource = Value
    		End Set
    	End Property
    	Private m_DataSource As SourceFiltered
    End Class
    La seconde, c'est de recevoir un objet de type Source :
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    Public Class Control
    	Public Property DataSource() As Source
    		Get
    			Return m_DataSource
    		End Get
    		Set
    			m_DataSource = Value
    		End Set
    	End Property
    	Private m_DataSource As Source
    End Class
    Les deux fonctionnent (sf étant la variable qu'on a utilisé un peu plus haut) :
    Code VB.NET : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Dim ctrl = New Control()
    ctrl.DataSource = sf
    L'avantage de la seconde, c'est que si le développeur veut m'envoyer un objet typé en SourceExtended, il pourra aussi... On va donc rester sur ça, ce qui est apparemment ce que tu souhaites faire.

    Ensuite, au sein de mon Control, je peux tester le type de la DataSource et effectuer un traitement en conséquence :
    Code VB.NET : 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
    Public Sub ProcessDataSource()
    	If TypeOf Me.DataSource Is SourceExtended Then
    		Me.ProcessSourceExtended()
    	ElseIf TypeOf Me.DataSource Is SourceFiltered Then
    		Me.ProcessSourceFiltered()
    	End If
    End Sub
     
    Private Sub ProcessSourceExtended()
    	Dim se As SourceExtended = TryCast(Me.DataSource, SourceExtended)
    	If se IsNot Nothing Then
    		' Le traitement pour un objet de type SourceExtended...
    	End If
    End Sub
     
    Private Sub ProcessSourceFiltered()
    	Dim sf As SourceFiltered = TryCast(Me.DataSource, SourceFiltered)
    	If sf IsNot Nothing Then
    		' Le traitement pour un objet de type SourceFiltered...
    	End If
    End Sub
    Bon, ça c'est un exemple assez simple. Est-ce que c'est ce que tu veux faire ?

    On peut aussi complexifier en rajoutant des Generics, on peut aussi passer par une interface ou encore une classe abstraite mais il faut en avoir l'utilité.
    Less Is More
    Pensez à utiliser les boutons , et les balises code
    Desole pour l'absence d'accents, clavier US oblige
    Celui qui pense qu'un professionnel coute cher n'a aucune idee de ce que peut lui couter un incompetent.

Discussions similaires

  1. Réponses: 8
    Dernier message: 12/09/2013, 14h25
  2. Réponses: 2
    Dernier message: 28/06/2007, 16h56
  3. [Composant] publier une propriété avec un type perso
    Par jpc34 dans le forum C++Builder
    Réponses: 6
    Dernier message: 12/10/2004, 09h39
  4. Réponses: 2
    Dernier message: 18/10/2003, 15h42
  5. Récupération valeur d'une propriété type TStrings
    Par Stéphane Vaillant dans le forum Langage
    Réponses: 2
    Dernier message: 01/03/2003, 12h47

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