none
Appel d'un control indirect RRS feed

  • Question

  • Avant toute chose, bonjour a tous et merci par avance de lire ces quelques lignes.

    Environnement : visual Basic 2010 express

    J'essaye d'accéder de manière indirecte a une suite de contrôles qui se trouve eux même dans d'autres contrôles.

    Exemple : un formulaire contenant un tabcontrol contenant des tabpages contenant des listviews contenant des colonnes.

    Le constructeur crée donc les insctructions suivante :

     Private
     Sub
     InitializeComponent()
     Me
    .TabPage = New
     System.Windows.Forms.TabControl()
     Me
    .TabPage1 = New
     System.Windows.Forms.TabPage()
     Me
    .ListFull = New
     System.Windows.Forms.ListView()
     Me
    .ColumnHeader1 = CType
    (New
     System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
     Me
    .ColumnHeader2 = CType
    (New
     System.Windows.Forms.ColumnHeader(), System.Windows.Forms.ColumnHeader)
    etc ....
     Me
    .TabPage.Controls.Add(Me
    .TabPage1)
    etc ...
     Me
    .TabPage1.Controls.Add(Me
    .ListFull)
    etc ...
     Me
    .ListFull.Columns.AddRange(New
     System.Windows.Forms.ColumnHeader() {Me
    .ColumnHeader1, Me
    .ColumnHeader2})
    etc ...
     Me
    .Controls.Add(Me
    .TabPage)
    etc ...
     End
     Sub
    
    
     Friend
     WithEvents
     TabPage As
     System.Windows.Forms.TabControl
     Friend
     WithEvents
     TabPage1 As
     System.Windows.Forms.TabPage
     Friend
     WithEvents
     ListFull As
     System.Windows.Forms.ListView
     Friend
     WithEvents
     ColumnHeader1 As
     System.Windows.Forms.ColumnHeader
     Friend
     WithEvents
     ColumnHeader2 As
     System.Windows.Forms.ColumnHeader
    

    La méthode directe serait :

    Me
    .TabPage1.text = "nouveaux texte"
    
    Me
    .ColumnHeader1.Text = "nouveaux texte"
    
    

    Hors dans mon cas, je cherche une méthode indirecte.

    Il existe celle via les controls

    Me
    .Controls("TabPage"
    ).Controls("TabPage1"
    ).text = "nouveaux texte"
    
    

    Mais le problème se complique au plus il a de profondeur dans l'arbre des controls.

    Donc vue que le constructeur crée

    Me
    .TabPage1
    
    et
    Friend
     WithEvents TabPage1
    
    , existe il une solution alternative ?

     

    Merci par avance pour vos réponses.

    Salutations

    Mortasgus

    • Modifié Mortasgus vendredi 25 juin 2010 08:41 maj
    vendredi 25 juin 2010 08:36

Réponses

  • Bonjour,

    Tout d'abord, la composition de contrôle n'est pas tellement bien supportée par les contrôles Windows Forms (inclure des ProgressBar dans un ListView). WPF est LA technologie qui permet de réaliser ce genre de chose...

    Lorsque vous ajoutez un contrôle dans un ListView, vous ne faites que l'encapsuler dedans comme dans un Panel. Le contrôle ListView affiche des ListViewItem et rien d'autre.

    Pour utiliser des groupes de contrôles utilisez des listes ou des tableaux d'objets. Voici un exemple...

    Dim l As List(Of ProgressBar)
    
    l.Add(New ProgressBar())
    l.Add(New ProgressBar())
    l.Add(New ProgressBar())
    
    l(0).Left = 10
    l(1).Left = 20

    Est-ce que cela répond à votre question ?

    Cordialement


    Gilles TOURREAU - MVP C# - MCTS Windows Forms - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    • Marqué comme réponse Mortasgus samedi 26 juin 2010 21:37
    samedi 26 juin 2010 19:11
    Modérateur

Toutes les réponses

  • désolé pour la mise en page mais l'éditeur du forum n'est pas terrible ^^
    vendredi 25 juin 2010 08:43
  • Bonjour,

    Hors dans mon cas, je cherche une méthode indirecte
    Que voulez vous dire ?

    Cordialement


    Gilles TOURREAU - MVP C# - MCTS Windows Forms - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    vendredi 25 juin 2010 14:03
    Modérateur
  • Bonjour et merci d'avoir pris le temps de répondre.

     

    En fait je ne sais pas vraiment. Juste que je connais 2 methodes actuellement qui donne la même chose qui sont :

    Me.tabpage1.text="nouveau texte"

    et

    Me.controls("tabpage").controls("tabpage1").text="nouveau texte"

     

    Hors dans mon cas de programmation, le premier est trop "rigide" pour pouvoir être utilisé dans mon programme et la deuxième deviens trop complexe au fur et a mesure que l'arbre s'agrandit et s'approfondit.

    Donc je cherche une troisieme solution si elle existe.

    Vue que le contructeur créé Me.tabpage1 = new .... et friends withevents tabpage1 ...

    Je me dit qu'autant il existe un moyen détourné d'appeler un sous-controle via le constructeur, soit par exemple

    me.appel_par_nom("tabpage1").text = "nouveau texte"

    ou

    appel_par_nom_d'un_dim("tabpage1").text = "nouveau texte"

     

    Enfin si vous voyez ce que je veux dire ^^

    Merci par avance de vos réponses

    vendredi 25 juin 2010 23:28
  • Re bonsoir,

    Entre temps, on ma proposé une autre solutions que je ne connaissais pas qui est :

    Dim test As Object = DirectCast(ColumnHeader1, ColumnHeader)
    test.text = "nouveau texte"

    Ça fait un petit peu avancer mon Schmilblick mais reste encore quelque souci ^^

    Reste a définir deux dim avant car ces noms et valeurs, je les récupère au format string.

    dim le_nom as quelque_chose = "ColumnHeader1"
    dim le_type as autre_chose = "ColumnHeader"
    Dim test As Object = DirectCast(le_nom, le_type)
    test.text = "test"

    Si vous connaissez la 3eme solutions et que vous savez comment l'amélioré, je suis preneur

    Si vous connaissez une 4eme ou 5eme (ou+) solutions je suis preneur aussi ;)

    Je cherche quelque chose de simple et efficace, qui fasse appel au nom du contrôle sans chichi ni froufrou ;)

    Merci par avance a tous

    samedi 26 juin 2010 00:08
  • Bonjour,

    J'ai vraiment du mal à comprendre votre problème...

    Si vous souhaitez accéder à un TabPage de votre TabControl directement, vous pouvez le faire via :

    Me.TabPage1

    Même chose pour les contrôles contenus dans vos TabPage...

    Cordialement


    Gilles TOURREAU - MVP C# - MCTS Windows Forms - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    samedi 26 juin 2010 08:43
    Modérateur
  • Bonjour,

    J'essaye de voir au delà de ce type de programmation. Ce type est tres bien pour un petit programme où il n'y a pas de "grosse" interaction avec le programme.

    Je vais essayez via un cas concret, mmm .... un form très complexe ou des contrôles sons ajouter et effacer a la volé en fonction de l'avancé du programme, une arborescence avec plein de sous sous sous sous control (ex : des combobox et des progressbar et des checkbox dans plusieurs listview dans des tabpage etc etc ... Des handles créé a la volé avec les combobox et les checkbox). Le truc bien gros et bien chiant quoi ^^

    A un moment donné, ce type de programmation simple ne suffit plus car comment appeler le bon combobox.

    Par exemple, On sais juste qu'il faut appeler le 12eme combobox qui a été créé a la volé.

    Comment l'appeler sans problème. aujourd'hui 10 combobox, demain 100, apres demain 1000.

    faire un if x=1 then me.combobox1.text = "eeee"

    if x=2 then ....

    jusqu'a 1000 alors qu'on ne sais pas combien il y en aura au moment t+1...

    De plus me.combobox1 n'existe pas puisqu'ils sont créé a la volé donc inexistant dans le contructeur.

     

    J'espère avoir été clair sur le risque de complexité qu'il y a dans se genre de programme.

    C'est pas évident a géré mais pas impossible vue que vb autorise se genre de création. Donc il doit exister un moyen de contrôlé tout ca.

     

    me.combobox1, impossible car innexistant dans le contructeur

    me.controls("tabpage").controls("tabpage1").control( ..... ).... , trop compliquer a programmer avec l'architecture de l'arboresence.

    directcast pourrais bien faire l'affaire mais mon niveau manque d'expertise pour amélioré la sequence.

     

    Je vous donne un autre exemple pour que vous puissiez y faire vos essaie

    Vous créé une form avec un tabcontrol. Dans le tabpage1 vous y ajouter une listview

    Dans le code :

        Public Sub New()
            InitializeComponent()
            Dim pro As New ProgressBar
            pro.Name = "pro1"
            Me.ListView1.Controls.Add(pro)
        End Sub

    Quand vous lancez le programme, vous voyez bien votre form contenant un tabcontrol avec 2 tabpage. Dans le tabpage1, un listview contenant 1 progressbar.

    Maintenant, comment changer la valeur de "pro1". Car "pro1" au format string est la seule chose que vous connaissez d'elle (et a la limite que c'est une "progressbar" valeur elle aussi au format string)

    Vous voyez mieux le hic j'espere ^^

     

    Je serais heureux d'en parler avec vous via un ts si vous voulez plus d'explications

     

    Merci encore par avance pour vos réponses.

    samedi 26 juin 2010 14:30
  • J'ai fait un essai rapide via notre dernier exemple et j'ai trouvé ceci a modifier dans le code:

      Dim col As New Collection
      Public Sub New()
        InitializeComponent()
        Dim pro As New ProgressBar
        pro.Name = "pro1"
        Me.ListView1.Controls.Add(pro)
        col.Add(pro, "pro1")
        Dim test As Object = DirectCast(col.Item("pro1"), ProgressBar)
        test.value = 30
      End Sub

    Et ca marche. Reste quelques détails a fignoler.

    sur la ligne

    Dim test As Object = DirectCast(col.Item("pro1"), ProgressBar)

    progressbar est une class objet et non un string

    existe t'il un moyen de nommé une classe objet via son nom ?

     

    Si vous voulez d'autres informations complémentaire, nous pouvons nous retrouver via un ts, skype etc ...

    Merci par avance de votre aide.

    samedi 26 juin 2010 15:00
  • Bonjour,

    Tout d'abord, la composition de contrôle n'est pas tellement bien supportée par les contrôles Windows Forms (inclure des ProgressBar dans un ListView). WPF est LA technologie qui permet de réaliser ce genre de chose...

    Lorsque vous ajoutez un contrôle dans un ListView, vous ne faites que l'encapsuler dedans comme dans un Panel. Le contrôle ListView affiche des ListViewItem et rien d'autre.

    Pour utiliser des groupes de contrôles utilisez des listes ou des tableaux d'objets. Voici un exemple...

    Dim l As List(Of ProgressBar)
    
    l.Add(New ProgressBar())
    l.Add(New ProgressBar())
    l.Add(New ProgressBar())
    
    l(0).Left = 10
    l(1).Left = 20

    Est-ce que cela répond à votre question ?

    Cordialement


    Gilles TOURREAU - MVP C# - MCTS Windows Forms - Architecte .NET/Consultant/Formateur - http://gilles.tourreau.fr
    • Marqué comme réponse Mortasgus samedi 26 juin 2010 21:37
    samedi 26 juin 2010 19:11
    Modérateur
  • Bonsoir,

    Oui je pense que cela répond a mes attentes. D'une manière ou d'un autre, créé une collection ou une list où est ajouter le nouveau control créé pour pouvoir l'appeler plus tard.

    Je vous remercie de votre aide.

    ps : oui pour le control dans un listview, c'est plus pour l'exemple qu'autre chose mais si vous avez quelques liens utile pour la technologie WPF, je suis preneur ^^

     

    Merci pour tout et a bientôt ^^

     

    ps2 : je viens de test un peu le wpf et sur le peu que j'ai vu, je suis bien content que tu m'est ouvert les yeux ^^ tres tres pratique point de vue design. toujours ouvert au suggestions et au liens utiles ^^. A bientôt ^^

     

    samedi 26 juin 2010 21:37