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 :

Création de sous objet dans une classe


Sujet :

VB.NET

  1. #1
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut Création de sous objet dans une classe
    Bonjour,

    Je suis en train de construire ma première classe (ouff!!)
    Ma problématique est assez générale mais je la présente à travers un exemple :
    Ma classe consiste à créer un modèle de chart personnalisé.
    Ce chart personnalisé contient 2 ChartAreas.
    Je suppose que cela commence donc ainsi :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    Public Class CustomChart
    Inherits system.Windows.forms.DataVisualization.Charting.Chart
     
    Sub New()
    MyBase.New()
     
    Me.ChartAreas.Add("c1")
    Me.ChartAreas.Add("c2")
    ...
    Mais je remarque que si, dans un form, j'ai déjà créé un contrôle CustomChart, et si j'en crée un deuxième, ça plante parce que le nom des ChartAreas est forcé et identique dans les deux instances de CustomChart.

    D'où ma question, comment faire en sorte que le nom de l'instance des ChartAreas soit créé par défaut et incrémenté en temps que de besoin (par exemple "ChartAreas1, ChartAreas2...")

  2. #2
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Bon alors je m'autocorrige :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    Public Class CustomChart
    Inherits system.Windows.forms.DataVisualization.Charting.Chart
     
    Private _pie as New ChartArea
    Private _bar as New ChartArea
     
    Sub New()
    MyBase.New()
     
     
    Me.ChartAreas.Add(pie)
    Me.ChartAreas.Add(bar)
    ...
    N'empêche, quand je crée une instance depuis la boîte à outil, le contrôle se se dessine avec une apparence qui laisse penser que ma sub new a été correctement interprétée et est complète , mais l'exécution en mode débug provoque une erreur me disant que "ChartArea1 existe déjà dans ChartAreaCollection". cette erreur survient en fin de l'instruction Form.show() où Form est le form dans lequel j'ai glissé mon CustomChart

    Je progresse, mais c'est pas encore ça ...

  3. #3
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    En fait je m'aperçois que le pb vient de la sub dans laquelle j'implémente mon code.

    Donc résumons ; je veux créer un CustomChart avec juste 2 ChartAreas et 2 séries. Le code "utile" se résume à ceci :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
            With Me
                .ChartAreas.Add(_pie)
                .ChartAreas.Add(_bar)
                .Legends.Add(_legend)
                .Series.Add(_series1)
                .Series.Add(_series2)
                End With
    Je m'aperçois que l'erreur provoquée citée plus haut vient du fait que je mets ce code dans la Sub New

    Je tatonne, je vois qu'il existe une sub InitialLayout mais si je mets le code dedans, le code est exécuté 2 fois :
    - une fois lors du rapatriement en mode design du contrôle : je me retrouve avec un chart contenant 3 chartAreas et 3 séries (j'en déduis au passage que, dans ce cas, le Chart créé contient déjà, par défaut, 1 chartarea et 1 série)
    - une autre fois lors de l'exécution : je me retrouve avec un chart contenant 5 chartareas et 5 séries.

    Donc le pb est que je n'ai pas compris, quand on personnalise un controle existant en créant une classe dérivée :
    - dans quel sub il faut implanter le code "utile" (par exemple, dans le tuto de P. Lasserre, on voit que ce code est implanté dans "OnPaint" pour un bouton)
    - dans quel cas il faut ajouter dans cette sub "Mybase.New" (dans la sub new) et "Mybase.mysub" (dans la protected sub mysub()). J'ai en effet tenté avec ou sans et je n'ai pas vu la différence.

    J'imagine que pour répondre à ces questions, il faut comprendre ce qui se passe dans la boîte du contrôle mère. Je n'ai pas trouvé dans les tutos réponse à ces questions.

    Qqun peut-il m'aider ou m'indiquer un tuto un peu plus complet que celui de P. Lasserre sur ces questions précises ?

  4. #4
    Membre chevronné Avatar de _Ez3kiel
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2013
    Messages
    836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    Par défaut
    Je n'y connais absolument rien en Chart, mais je veux bien essayer de t'aider.

    Déjà, j'ai du mal à saisir ton souci, concrètement.

    Dans ton control personnalisé, tu dois lui donner un constructeur Public Sub New()Ton control du fait qu'il hérite de system.Windows.forms.DataVisualization.Charting.Chart, il possède les propriétés de cette classe Windows, mais il faut les initialiser, et c'est ce que fait la Public Sub New() de la classe de Windows. Mais dans ta classe à toi ce n'est pas fait, bien que tu hérites de cette dernière.
    Du coup, il faut que tu appelles la Public Sub New() de la classe windows dans ta propre Public Sub New(), et ça se fait avec MyBase.New() (MyBase désignant la classe mère dont tu hérites)

    D'un point de vue code :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
            Public Sub New()
                MyBase.New() ' <--- Appelle le New de system.Windows.forms.DataVisualization.Charting.Chart
     
            End Sub
    Donc résumons ; je veux créer un CustomChart avec juste 2 ChartAreas et 2 séries.
    Et donc où est le souci ?

    Dans ton application, tu instancieras tonControlChart de type CustomChart et tu joueras avec ses properties .chartAreas() et .Series() que ta classe possédera vu qu'elle hérite de celle de Windows.


    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    Public Class Form1
     
    Private sub bttn_click(sender,e) handles bttn.click
     
    Dim tonControlChar as New CustomChart
    Dim pie as new ChartArea
    Dim bar as new ChartArea
     
    tonControlChart.chartAreas.Add(pie)
    tonControlChart.chartAreas.Add(bar)
     
     
    end sub
    End class
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  5. #5
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Bonjour Ez3kiel et merci de ton aide.

    Alors quand je dis que je ma classe se résume à la création de 2 chartareas et 2 series, c'est pour simplifier à sa plus simple expression pour montrer aussi où se trouve l'exception générée.

    Donc voici le code simplifié mais complet de la classe :
    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
    Imports System.Windows.Forms.DataVisualization.Charting
     
    Public Class CustomChart
        Inherits System.Windows.Forms.DataVisualization.Charting.Chart
     
        Private components As System.ComponentModel.IContainer
        Private _pie As New ChartArea
        Private _bar As New ChartArea
        Private _series1 As New Series
        Private _series2 As New Series
        Private _legend As New Legend
     
     
        Public Sub New()
            MyBase.New()
     
            'affichage graphique
            With Me
                .ChartAreas.Add(_pie)
                .ChartAreas.Add(_bar)
                .Legends.Add(_legend)
                .Series.Add(_series1)
                .Series.Add(_series2)
     
            End With
            '...
        End Sub
    End Class
    Si je n'avais que cela à faire, je créerais ces éléments dans le form comme tu le préconises, mais c'est en fait le préambule à beaucoup d'autres propriétés des constituants du Chart que je fige au travers d'un code basique qui vient remplacer les points de suspension de la ligne 26. Je ne les détaille pas (sauf si tu le souhaites) car ce code n'apporte rien à la résolution du pb. Il y en a une page A4 (voire 2) de lignes de code car je fige pas mal de paramètres des chart areas + des séries + de la légende etc... D'où l'intérêt de le faire une fois et une seule dans un customchart que j'appelle ensuite plusieurs fois dans mon projet.

    Donc, si tu veux bien, on peut se concentrer sur le code ci-dessus même si sur le fond, je suis d'accord, il ne semble pas justifier la création d'une classe spécifique.

    J'ai donc bien mis la sub New (j'avais testé avec et sans) mais ça n'empêche pas l'erreur évoquée précédemment.

    Je crée un form1, j'y glisse le CustomChart depuis la boîte à outil. tout se passe bien.
    Dans mon form principal je crée un bouton pour ouvrir le form1

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    Private Sub Formprincipal_bouton_click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MonBouton.Click
            Form1.Show()
        End Sub
    Un débug pas à pas montre que le code se déroule dans l'ordre suivant :
    - lecture de form1.show()
    - lecture de la sub New de la classe CustomChart jusqu'à End Sub
    -surlignage en jaune de Form1.Show avec l'exception générée "Une erreur s'est produite lors de la création du formulaire. Pour plus d'informations, consultez Exception.InnerException. L'erreur est : Un élément de graphique portant le nom « ChartArea1 » existe déjà dans « ChartAreaCollection »."

    A fait 2 jours que je suis sur ce pb. Je n'ai pas trouvé la solution mais j'ai émis des hypothèses :
    - la sub New est lue 2 fois : une fois lorsque je glisse le contrôle depuis la boîte à outil vers le form, une 2ème fois lorsque j'exécute l'appli (comme le montre le pas à pas sus-évoqué)
    - le code que j'ai dénommé "utile" ne doit pas se trouver dans la sub new mais ailleurs. Si c'est le cas, où ? Ce qui me fait penser à cela c'est qu'il y a pas mal d'exemples de boutons personnalisés (notamment dans le tuto de P. Lasserre) où les modifications sont mises dans le OnPaint et non dans la Sub New.

    J'espère que c'est plus clair...

  6. #6
    Membre expérimenté
    Homme Profil pro
    Développeur .Net / Delphi
    Inscrit en
    Juillet 2002
    Messages
    738
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Eure (Haute Normandie)

    Informations professionnelles :
    Activité : Développeur .Net / Delphi
    Secteur : Finance

    Informations forums :
    Inscription : Juillet 2002
    Messages : 738
    Points : 1 745
    Points
    1 745
    Par défaut
    Bonjour,

    Je ne connais pas non plus vraiment Chart.
    A priori, l'ajout des ChartArea dans la collection a toute sa place au niveau du constructeur de la classe (Sub New()).
    Note : Les Exemples de code que tu as pu voir de boutons personnalisés sont situés dans l'évènement OnPaint car il s'agit de code de dessins. Cet évènement est généré par windows au moment du rendu lors de chaque rafraîchissement du control. Pour dessiner, c'est là que ça se passe. Mais ce n'est pas ton cas...

    Concernant l'erreur sur les ChartArea, ne faut-il pas leur donner un nom ? Il y a une surcharge du constructeur permettant de le faire :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    Private _pie As New ChartArea("pie")
        Private _bar As New ChartArea("bar")
    Cela évitera d'avoir 2 ChartArea1...

    eb.

  7. #7
    Membre chevronné Avatar de _Ez3kiel
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2013
    Messages
    836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    Par défaut
    Citation Envoyé par noftal Voir le message
    - la sub New est lue 2 fois : une fois lorsque je glisse le contrôle depuis la boîte à outil vers le form, une 2ème fois lorsque j'exécute l'appli (comme le montre le pas à pas sus-évoqué)
    C'est une hypothèse exacte, lorsque tu déposes ton control dans le designer, il doit écrire le code de celui-ci dans son Designer.Vb afin de le déclarer et de définir les valeurs de ses propriétés, et pour ce faire, il lance le Sub New pour instancier ces valeurs.


    Ton souci ici c'est que quand tu déposes ton customControl, il fait MyBase.New() (Donc le New de la classe Windows) OR ce New instancie par défaut une ChartArea qu'il appelle ChartArea1, une Legend qu'il appelle Legend1 et une Serie qu'il appelle Series1.

    PUIS, toi tu lui dis d'instancier _pie, _bar, _serie12, etc, Or par défaut, tes ChartArea et autres n'ayant pas de nom, elle prennent un nom "par défaut" qui est malheureusement ChartArea1, ce qui fait planter car cette dernière a déjà été instancié par le MyBase.New()


    Soit tu donnes un nom à tes instances (autres que les noms qu'utilisent Windows comme ChartArea1 etc):

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
        Private _pie As New ChartArea("CA1")
        Private _bar As New ChartArea("CA2")
        Private _series1 As New Series("S1")
        Private _series2 As New Series("S2")
        Private _legend As New Legend("L1")
    Mais tu auras ton graphique ET le graphique d'initialisation de Windows.

    Soit tu te passes de ton MyBase.New(), ainsi, tes instances _pie etc prendra la valeur ChartArea1 par défaut, et vu que Windows n'aura pas instancié ses propres ChartArea, pas de conflit de nom !

    Ps: N'oublie pas de supprimer ton control de ton Form et de le remettre quand tu fais des tests, il régénère son Designer à chaque fois



    OU 3éme solution, tu fais les 2 du haut, pas de MyBase.New ET nommage des variables.
    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
    Imports System.Windows.Forms.DataVisualization.Charting
     
    Public Class CustomChart
        Inherits System.Windows.Forms.DataVisualization.Charting.Chart
     
     
        Private _pie As New ChartArea("CA1")
        Private _bar As New ChartArea("CA2")
        Private _series1 As New Series("S1")
        Private _series2 As New Series("S2")
        Private _legend As New Legend("L1")
     
        Public Sub New()
            ' MyBase.New() 'On ne le met pas comme ça Windows n'instancie pas de ChartArea par défaut
     
     
     
            With Me
                .ChartAreas.Add(_pie)
                .ChartAreas.Add(_bar)
                .Legends.Add(_legend)
                .Series.Add(_series1)
                .Series.Add(_series2)
     
            End With
        End Sub
     
     
    End Class
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  8. #8
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Si je te suis bien solution 2 = solution 3 sans le MyBase.New ?

    En tout cas, dans les 2 cas, j'ai exactement le même message : "Une erreur s'est produite lors de la création du formulaire. Pour plus d'informations, consultez Exception.InnerException. L'erreur est : Un élément de graphique portant le nom « pie » existe déjà dans « ChartAreaCollection »."

    Ceci me paraît assez logique.

    En effet, quand tu dis :
    Ton souci ici c'est que quand tu déposes ton customControl, il fait MyBase.New() (Donc le New de la classe Windows) OR ce New instancie par défaut une ChartArea qu'il appelle ChartArea1, une Legend qu'il appelle Legend1 et une Serie qu'il appelle Series1.
    je pense qu'il y a une erreur. N'est-ce pas plutôt :
    Ton souci ici c'est que quand tu déposes ton customControl, il fait Sub New() (Donc le New de la classe Windows) OR ce New instancie par défaut une ChartArea qu'il nomme comme le prévoit la sub New, ....
    Ceci explique que la sub New est lue 2 fois. Donc quel que soit le nom par défaut des mes objets (pie ou celui de Windows), il y aurait bien double création avec le même nom.

  9. #9
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    J'ai fait un test qui vous parlera peut-être (moi ça me laisse sec sinon que ça confirme mon inteprétation).

    J'ai utilisé le code de Ez3kiel (avec ou sans le Mybase.new : cela revient au même).
    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
    Imports System.Windows.Forms.DataVisualization.Charting
     
    Public Class CustomChart
        Inherits System.Windows.Forms.DataVisualization.Charting.Chart
     
        Private components As System.ComponentModel.IContainer
        Private _pie As New ChartArea("pie")
        Private _bar As New ChartArea("bar")
        Private _series1 As New Series("Series1")
        Private _series2 As New Series("Series2")
        Private _legend As New Legend("Legend1")
     
     
        Public Sub New()
            MyBase.New() 'on peut l'enlever ou le laisser cela revient au même du point de vue du fonctionnement apparent
     
            'affichage graphique
            With Me
                .ChartAreas.Add(_pie)
                .ChartAreas.Add(_bar)
                .Legends.Add(_legend)
                .Series.Add(_series1)
                .Series.Add(_series2)            
            End With
        End Sub
    End Class
    J'ai glissé un CustomChart dans mon form1.
    Dans le designer, j'ai renommé les objets qu'il contient dont les noms correspondent au code de ma classe:
    -pie => ca1
    -bar => ca2
    - Legend1 => L
    - Series1 => S1
    - Series2 => S2

    Puis j'ai rajouté des espions après mon "form1.show()

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
     Form1.Show()
            Dim nom1 As String = Form1.CustomChart1.ChartAreas(0).Name
            Dim nom2 As String = Form1.CustomChart1.ChartAreas(1).Name
            Dim nom3 As String = Form1.CustomChart1.ChartAreas(2).Name
            Dim nom4 As String = Form1.CustomChart1.ChartAreas(3).Name
    Le debug pas à pas montre que :
    - Form1 s'ouvre avec 1 chart contenant 4 Chartareas (d'où l'idée de mes 4 espions)
    -nom1 = pie
    -nom2 = bar
    -nom3 = ca1
    -nom4 = ca2

    La seule info nouvelle apportée par ce test est que l'instance New est d'abord réalisée par le code avant d'être réalisée via le designer ; je m'attendais plus à avoir :
    -nom1 = ca1
    -nom2 = ca2
    -nom3 = pie
    -nom4 = bar

    Mais peut-être que cela va vous donner des idées ?

  10. #10
    Membre chevronné Avatar de _Ez3kiel
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2013
    Messages
    836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    Par défaut
    J'ai retesté ce que j'avais fait hier, et maintenant ça ne marche plus ...


    Citation Envoyé par noftal Voir le message
    - Form1 s'ouvre avec 1 chart contenant 4 Chartareas (d'où l'idée de mes 4 espions)
    -nom1 = pie
    -nom2 = bar
    -nom3 = ca1
    -nom4 = ca2

    La seule info nouvelle apportée par ce test est que l'instance New est d'abord réalisée par le code avant d'être réalisée via le designer ; je m'attendais plus à avoir :
    -nom1 = ca1
    -nom2 = ca2
    -nom3 = pie
    -nom4 = bar

    Mais peut-être que cela va vous donner des idées ?
    Non c'est le fonctionnement normal pour moi, il lit une première fois la classe pour créer le control, donc a les valeurs qu'elle lui donne, puis ces valeurs sont réaffectés (par toi ici) dans le designer...

    Bref, le souci est que, on le sait, il y a 2 passages de New(), donc double ajout, et que ça fait planter. Le MyBase.New() n'en est pas la cause en fait.

    Windows a réussi à gérer ça, lorsque tu déposes un Chart sur le Designer, le graph' apparaît en prévisu, puis lorsque tu lances le log, on voit le nom des chartAreas apparaître, mais la prévisu du graph qu'on a vu dans le Designer n'est plus là.(Voir Pièce jointe)

    Comme solution (pas top), on peut le custom control au niveau du code dans l'event Load de ta Form1 par exemple:

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
     
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
     
            Dim CustChar As New CustomChart
     
            Controls.Add(CustChar)
     
        End Sub
    Y'aura pas double passage de New() donc c'est bon (mais y'aura pas la prévisu au niveau du Designer, c'est ce qui m'embête )

    Ou la 1ère solution que je t'avais donnée, ajouter les ChartAreas et données non pas dans ta classe, mais dans l'appli ...

    Je continue de chercher je te tiens au courant si je trouves du mieux.
    Images attachées Images attachées  
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  11. #11
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Y'aura pas double passage de New() donc c'est bon (mais y'aura pas la prévisu au niveau du Designer, c'est ce qui m'embête )
    Oui, cela pose un soucis : si je veux modifier des propriétés du control non régies déjà par ma classe, je ne peux pas le faire.

    J'ai testé hier une autre solution :
    - créer dans la classe une méthode que j'ai appelée Initialize dans lequel je reporte tout le code que je souhaitais mettre dans sub new.
    - Appeler cette méthode dans le form :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
     
            CustomChart1.Initialize()
     
        End Sub
    Au moins, j'ai bien toujours la possibilité de créer mon contrôle depuis la boîte à outil et de modifier ses propriétés dans le designer.

    L'inconvénient, c'est que le contrôle apparaissant dans le designer est un contrôle Chart simple non customisé. Donc il ne contient (par exemple) qu'un ChartArea et une seule Série. Donc, tout comme avec ta solution, je ne peux pas accéder en mode design aux propriétés du deuxième ChartArea et de la 2ème série.

    Un autre inconvénient est que, au bout d'un certain nombre d'exécutions, le contenu du contrôle dans le designer n'est plus visible : il est remplacé par une phrase indiquant qu'il y a un pb, le cadre reste donc vide hormis cette phrase. Enfin, ce n'est pas un inconvénient mais plutôt un sujet d'inquiétude sur l'intégrité de ma classe.

    Ce qui est bizarre dans tout ça, c'est que je croyais que le pb était générique avec toutes les classes héritées dans lesquelles la sub new demande la création d'un sous-objet, d'où l'intitulé de ce topic.
    En fait il n'en est rien. J'ai fait un test en créant une classe héritant de la classe GroupBox en y créant, dans la sub new, un bouton radio, et ça marche très bien.
    Crois-tu possible que ce pb soit spécifique à Chart (défaut de conception du contrôle Chart) ?

  12. #12
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Windows a réussi à gérer ça, lorsque tu déposes un Chart sur le Designer, le graph' apparaît en prévisu, puis lorsque tu lances le log, on voit le nom des chartAreas apparaître, mais la prévisu du graph qu'on a vu dans le Designer n'est plus là.(Voir Pièce jointe)
    Ca c'est normal : le graphique que tu vois en mode design est symbolique.
    Quand tu lances l'exécution, le chart cherche la source de données pour dessiner les histogrammes. Comme à ce stade, tu ne l'as pas indiquée (ni par le code ni dans le designer), il n'affiche rien. Sauf erreur, tu as la même phénomène si tu rapatries un simple Chart dans ton Form

  13. #13
    Membre chevronné Avatar de _Ez3kiel
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2013
    Messages
    836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    Par défaut
    Citation Envoyé par noftal Voir le message
    Oui, cela pose un soucis : si je veux modifier des propriétés du control non régies déjà par ma classe, je ne peux pas le faire.
    Tu peux par le code, vu que ton control hérite de Chart mais tu n'auras pas la prévisu.

    Citation Envoyé par noftal Voir le message
    J'ai testé hier une autre solution :
    - créer dans la classe une méthode que j'ai appelée Initialize dans lequel je reporte tout le code que je souhaitais mettre dans sub new.
    - Appeler cette méthode dans le form :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
     
        Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
     
            CustomChart1.Initialize()
     
        End Sub
    Au moins, j'ai bien toujours la possibilité de créer mon contrôle depuis la boîte à outil et de modifier ses propriétés dans le designer.

    L'inconvénient, c'est que le contrôle apparaissant dans le designer est un contrôle Chart simple non customisé. Donc il ne contient (par exemple) qu'un ChartArea et une seule Série. Donc, tout comme avec ta solution, je ne peux pas accéder en mode design aux propriétés du deuxième ChartArea et de la 2ème série.

    Un autre inconvénient est que, au bout d'un certain nombre d'exécutions, le contenu du contrôle dans le designer n'est plus visible : il est remplacé par une phrase indiquant qu'il y a un pb, le cadre reste donc vide hormis cette phrase. Enfin, ce n'est pas un inconvénient mais plutôt un sujet d'inquiétude sur l'intégrité de ma classe.
    L'idée était bonne, mais on se heurte toujours au même problème.


    Citation Envoyé par noftal Voir le message
    Ce qui est bizarre dans tout ça, c'est que je croyais que le pb était générique avec toutes les classes héritées dans lesquelles la sub new demande la création d'un sous-objet, d'où l'intitulé de ce topic.
    En fait il n'en est rien. J'ai fait un test en créant une classe héritant de la classe GroupBox en y créant, dans la sub new, un bouton radio, et ça marche très bien.
    Crois-tu possible que ce pb soit spécifique à Chart (défaut de conception du contrôle Chart) ?
    Oui le fonctionnement est plutôt bizarre, j'ai fait des classes dérivées pour plein de controls, et j'ai jamais rencontré ce souci. Après j'ai toujours du mal à croire aux défauts de conception dans le framework .Net, c'est distribué à des millions de codeur, donc j'estime qu'ils l'ont bien pensé avant.
    Pour moi il doit y avoir une logique d'utilisation de l'héritage d'un Chart, mais on la trouve pas.

    Citation Envoyé par noftal
    Ca c'est normal : le graphique que tu vois en mode design est symbolique.
    Quand tu lances l'exécution, le chart cherche la source de données pour dessiner les histogrammes. Comme à ce stade, tu ne l'as pas indiquée (ni par le code ni dans le designer), il n'affiche rien. Sauf erreur, tu as la même phénomène si tu rapatries un simple Chart dans ton Form
    Je ne savais pas, merci pour la précision.
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  14. #14
    Membre actif
    Inscrit en
    Juillet 2013
    Messages
    777
    Détails du profil
    Informations forums :
    Inscription : Juillet 2013
    Messages : 777
    Points : 275
    Points
    275
    Par défaut
    Tu peux par le code, vu que ton control hérite de Chart mais tu n'auras pas la prévisu.
    Oui, c'est ce que je voulais dire

  15. #15
    Membre chevronné Avatar de _Ez3kiel
    Homme Profil pro
    Développeur .NET
    Inscrit en
    Janvier 2013
    Messages
    836
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 32
    Localisation : France, Finistère (Bretagne)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : Administration - Collectivité locale

    Informations forums :
    Inscription : Janvier 2013
    Messages : 836
    Points : 1 961
    Points
    1 961
    Par défaut
    Toujours pas avancé, l'aide d'un "connaisseur", ou de quelqu'un qui a déjà eu à créer sa classe perso dérivant de l'officielle de Chart, est la bienvenue.
    Aider les autres, c'est encore la meilleure façon de s'aider soi-même. Martin Gray

    ToDo : Faire une ToDo List

  16. #16
    Expert confirmé
    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 : 41
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    J'suis pas un expert mais ça m'intrigue alors je vais tester votre schmilblik ^^
    Kropernic

  17. #17
    Expert confirmé
    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 : 41
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    Suggestion :

    Si les propriétés que tu désires fixées sont des propriétés des chartareas, series et legend, pourquoi ne pas créé des classes custom héritées de ces classes de base et modifier le chart uniquement pour qu'il accepte tes classes custom uniquement.

    Après, pour ajouter les chartareas, tu le fais en mode design ou via le code de l'application mais pas dans le controle.

    Après tout, ça n'a pas de sens de le faire dans le contrôle. Sinon faut commencer à faire un contrôle pour quand on veut 1 chartarea, 2 chartareas, 3 chartareas, etc.

    Non ?

    EDIT : Il n'est pas non plus impossible que le contrôle chart ait un petit bug et que donc, hérité de ce dernier pose un souci. Quand on voit l'état du contrôle MonthCalendar... (qui s'est amélioré mais ce n'est pas encore ça).
    Kropernic

  18. #18
    Expert confirmé
    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 : 41
    Localisation : Belgique

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

    Informations forums :
    Inscription : Juillet 2006
    Messages : 3 932
    Points : 4 239
    Points
    4 239
    Par défaut
    En attendant d'avoir une réponse à ma suggestion, j'ai produit ceci qui mélange ma suggestion et le désir de noftal.

    Je peux ajouter à la form. Après, ça m'affiche une jolie croix rouge au runtime mais j'imagine que c'est normal vu qu'il n'y aucune info d'aucune sorte pour savoir comment dessiner les graphiques^^.

    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
    Imports System.Windows.Forms.DataVisualization.Charting
     
    Public Class CustomChart
        Inherits Chart
     
        Public Sub New()
            MyBase.New()
            Dim ca1 As New CustomChartArea("ca1")
            Dim ca2 As New CustomChartArea("ca2")
            Me.ChartAreas.Add(ca1)
            Me.ChartAreas.Add(ca2)
            Me.BackColor = Color.LightBlue
        End Sub
     
        <System.ComponentModel.DesignerSerializationVisibility(System.ComponentModel.DesignerSerializationVisibility.Hidden)>
        Public Overloads Property ChartAreas As New List(Of CustomChartArea)
    End Class
     
    <SerializableAttribute()> _
    Public Class CustomChartArea
        Inherits ChartArea
     
        Public Sub New()
            MyBase.New()
        End Sub
     
        Private _alignmentStyle As AreaAlignmentStyles
        Public Overloads ReadOnly Property AlignmentStyle As AreaAlignmentStyles
            Get
                Return Me._alignmentStyle
            End Get
        End Property
     
        Private _shadowColor As Color
        Public Overloads ReadOnly Property ShadowColor As Color
            Get
                Return _shadowColor
            End Get
        End Property
     
        Public Sub New(name As String)
            MyBase.New(name)
            Me._alignmentStyle = AreaAlignmentStyles.AxesView
            Me._shadowColor = Color.Azure
        End Sub
     
    End Class
    Kropernic

Discussions similaires

  1. [POO] Un objet dans une classe
    Par Arnich dans le forum Langage
    Réponses: 6
    Dernier message: 25/11/2007, 22h46
  2. Réponses: 1
    Dernier message: 19/07/2007, 12h39
  3. list d'objet dans une classe
    Par wadcyr8_197 dans le forum C++
    Réponses: 10
    Dernier message: 04/07/2007, 15h34
  4. Réponses: 8
    Dernier message: 12/04/2007, 11h32
  5. [POO] import d'objet dans une classe
    Par wdionysos dans le forum Langage
    Réponses: 3
    Dernier message: 01/04/2006, 21h05

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