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

Windows Forms Discussion :

[Treeview] DrawNode = Sapin de Noel ?!


Sujet :

Windows Forms

  1. #1
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 183
    Points : 79
    Points
    79
    Par défaut [Treeview] DrawNode = Sapin de Noel ?!
    Hello,

    j'ai un Treeview qui est en mode OwnerDrawText.

    Treeview appelle bien ma fonction DrawNode dans laquelle je positionne e.DrawDefault à true afin que le système dessine le texte, moi je ne veux qu'ajouter une icône à droite du texte.

    Tout ça marche plutôt bien ... sauf que ...

    Le hic : lors du remplissage de ma treeview, je vois toutes mes icônes qui se dessinent en haut de ma Treeview ?!
    ... même avec des BeginUpdate() / EndUpdate()

    La question : pourquoi ?

    Que faire :

    > Est-ce que je dois déterminer si mon Treeview est en "update" et donc ne pas tracer mes icônes ?

    > Est-ce un problème de bounds ? ... en effet, je dessine à coté du bound actuel de la node ... dois-je l'agrandir pour inclure mon icône ?
    ( ou surcharger le getbound() pour inclure mon icône ? )

    Merci de vos lumières

  2. #2
    Membre régulier
    Homme Profil pro
    Inscrit en
    Mai 2005
    Messages
    183
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 47
    Localisation : France, Drôme (Rhône Alpes)

    Informations forums :
    Inscription : Mai 2005
    Messages : 183
    Points : 79
    Points
    79
    Par défaut
    Je crois avoir trouvé une "bidouille"' : quand ma fonction DrawNode() est appelée dans un update, j'ai Bound.X=-1 et Bound.Y=0 ... et donc je peux filtrer ...

    Mais est-ce documenté ? ...

  3. #3
    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 Seb.26
    Pas de bidouile mon vieux.
    Voici comment traiter ce cas simple avec un exemple tire de la sdk msdn.

    il faut se servir du rectangle de selection car il est dessine avant le texte du node comme bacground du controle.
    De plus ce rectangle a 2 etats (selectione et non selectionE =>2 couleurs).

    Ensuite est dessine le texte du node et apres tout ce peut rajouter par exemple un message string ou un icon.
    e.boounds est en lecture seile et sert pour le dessin par defaut :
    -du rectangle de selection
    -du texte du node.....


    code vb.net :
    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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
     
    Public Class frmTreeViewDrawItemIconD
     
        Private tagIcon As Icon = My.Resources.Boss
     
        Private Sub frmTreeViewDrawItem_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
            Me.TreeView1.DrawMode = TreeViewDrawMode.OwnerDrawText
        End Sub
        Private Sub btnPopulate_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnPopulate.Click
            InitializeTreeView()
        End Sub
        ' Populates a TreeView control with example nodes. 
        Private Sub InitializeTreeView()
            TreeView1.BeginUpdate()
            TreeView1.Nodes.Add("Parent")
            TreeView1.Nodes(0).Tag = tagIcon
            TreeView1.Nodes(0).BackColor = Color.Yellow
     
            TreeView1.Nodes(0).Nodes.Add("Child 1")
            TreeView1.Nodes(0).Nodes.Add("Child 2")
     
            TreeView1.Nodes(0).Nodes(1).Nodes.Add("Grandchild")
            TreeView1.Nodes(0).Nodes(1).Nodes(0).Nodes.Add("Great Grandchild")
            TreeView1.Nodes(0).Nodes(1).Nodes(0).Tag = tagIcon
            TreeView1.Nodes(0).Nodes(1).Nodes(0).BackColor = Color.Yellow
     
            TreeView1.Nodes(0).Nodes.Add("Child 3")
            TreeView1.Nodes(0).Nodes(2).Tag = tagIcon
            TreeView1.Nodes(0).Nodes(2).BackColor = Color.Yellow
     
            TreeView1.EndUpdate()
        End Sub
        'version icone à droite
        Private Sub TreeView1_DrawNode(ByVal sender As Object, ByVal e As System.Windows.Forms.DrawTreeNodeEventArgs) Handles TreeView1.DrawNode
     
            ' Retrieve the node font. If the node font has not been set,
            ' use the TreeView font.
            If e.Node.NodeFont Is Nothing Then
                e.Node.NodeFont = CType(sender, TreeView).Font
            End If
     
     
            ' Draw the background and node text for a selected node.
            If (e.State And TreeNodeStates.Selected) <> 0 Then
     
                ' Draw the background of the selected node. The NodeBounds
                ' method makes the highlight rectangle large enough to
                ' include the icon of a node tag, if one is present.
     
                e.Graphics.FillRectangle(Brushes.Blue, NodeBounds(e.Node))
     
                ' Draw the node text.
                e.Graphics.DrawString(e.Node.Text, e.Node.NodeFont, Brushes.Red, _
                   e.Bounds.Left, e.Bounds.Top)
     
                ' Use the default background and node text.
            Else
                e.DrawDefault = True
            End If
     
            ' If a node tag is present, draw its icon 
            ' to the right of the label text.
            If (e.Node.Tag IsNot Nothing) Then
     
                e.Graphics.DrawIcon(CType(e.Node.Tag, Icon), _
                NodeBounds(e.Node).Right - CType(e.Node.Tag, Icon).Width, NodeBounds(e.Node).Top)
     
            End If
     
            ' If the node has focus, draw the focus rectangle large, making
            ' it large enough to include the icon of the node tag, if present.
            If (e.State And TreeNodeStates.Focused) <> 0 Then
                Dim focusPen As New Pen(Color.Black)
                Try
                    focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot
                    Dim focusBounds As Rectangle = NodeBounds(e.Node)
                    focusBounds.Size = New Size(focusBounds.Width - 1, _
                        focusBounds.Height - 1)
                    e.Graphics.DrawRectangle(focusPen, focusBounds)
                Finally
                    focusPen.Dispose()
                End Try
            End If
        End Sub
        '***   CALCUL DU RECTANGLE DE SELECTION    ***
     
        'Returns the bounds of the specified node, including the region 
        'occupied by the node label and any node tag displayed.
        Private Function NodeBounds(ByVal node As TreeNode) As Rectangle
     
            'Set the return value to the normal node bounds.
            Dim bounds As Rectangle = node.Bounds
            If (node.Tag IsNot Nothing) Then
     
                'Retrieve a Graphics object from the TreeView handle
                'and use it to calculate the display width of the tag
     
                Dim g As Graphics = TreeView1.CreateGraphics()
     
                'Adjust the node bounds using the calculated value.
     
                '1- mesure  largeur du node.text suivant 
                'le NodeFont utilise & ajuste le rectangle de selection 
     
                Dim tagWidth As Integer = CInt(g.MeasureString( _
                   node.Text, node.NodeFont).Width)
                bounds.Width = tagWidth
     
     
                '2-mesure la largeur d'icon 
                tagWidth = CType(node.Tag, Icon).Width
     
                'decale le sommet -x- du  rectangle de selection 
                bounds.Offset(tagWidth / 2, 0)
     
                ' ------ rappel :une dilatation accroit a gauche et à droite simuultanement).... 
                'dilate  suivant -x-  de tagWidth / 2  tel que
                bounds = Rectangle.Inflate(bounds, tagWidth / 2, 0)
                g.Dispose()
            End If
            Return bounds
        End Function 'NodeBounds
     
     
     
    End Class
    code csharp:
    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
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
     
     
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;
     
    namespace TreeViewDrawItemCSharp
    {
     
        //private System.  Icon tagIcon = My.Resources.Boss;
        public partial class Form1 : Form
        {
            //charge un icone Boss.ico a partir des resources du projet
             private Icon  tagIcon =TreeViewDrawItemCSharp.Properties.Resources.Boss;
            public Form1()
            {
                InitializeComponent();
            }
            private void Form1_Load(object sender, EventArgs e)
            {
                this.treeView1.DrawMode = TreeViewDrawMode.OwnerDrawText;
            }
            private void button1_Click(object sender, EventArgs e)
            {
                InitializeTreeView();
            }
            // Populates a TreeView control with example nodes. 
            private void InitializeTreeView()
            {
                treeView1.BeginUpdate();
               // un icon pour le parent
                treeView1.Nodes.Add("Parent");
                treeView1.Nodes[0].Tag = tagIcon;
                treeView1.Nodes[0].BackColor = Color.Yellow;
     
     
                treeView1.Nodes[0].Nodes.Add("Child 1");
                treeView1.Nodes[0].Nodes.Add("Child 2");
     
                // un icon pour le petit fils
                treeView1.Nodes[0].Nodes[1].Nodes.Add("Grandchild");
                treeView1.Nodes[0].Nodes[1].Nodes[0].Nodes.Add("Great Grandchild");
                treeView1.Nodes[0].Nodes[1].Nodes[0].Tag = tagIcon;
                treeView1.Nodes[0].Nodes[1].Nodes[0].BackColor = Color.Yellow;
     
                // un icon pour le  3 fils
                treeView1.Nodes[0].Nodes.Add("Child 3");
                treeView1.Nodes[0].Nodes[2].Tag = tagIcon;
                treeView1.Nodes[0].Nodes[2].BackColor = Color.Yellow;
     
     
     
                treeView1.EndUpdate();
            }
     
            private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e)
            {
                // Retrieve the node font. If the node font has not been set,
                // use the TreeView font.
                if (e.Node.NodeFont == null) e.Node.NodeFont = ((TreeView)sender).Font;
     
     
                // Draw the background and node text for a selected node.
                if ((e.State & TreeNodeStates.Selected) != 0)
                {
                    // Draw the background of the selected node. The NodeBounds
                    // method makes the highlight rectangle large enough to
                    // include the text of a node tag, if one is present.
                    e.Graphics.FillRectangle(Brushes.Green, NodeBounds(e.Node));
     
     
                    // Draw the node text.
                    e.Graphics.DrawString(e.Node.Text, e.Node.NodeFont , Brushes.White,
                        Rectangle.Inflate(e.Bounds, 2, 0));
                }
     
                // Use the default background and node text.
                else
                {
                    e.DrawDefault = true;
                }
     
     
     
                // If a node tag is present, draw its icon 
                // to the right of the label text.
                if (e.Node.Tag != null)
                {
                    Icon icn = (Icon)(e.Node.Tag);
                    e.Graphics.DrawIcon(icn,
                NodeBounds(e.Node).Right - icn.Width, NodeBounds(e.Node).Top);
     
                }
     
                // If the node has focus, draw the focus rectangle large, making
                // it large enough to include the text of the node tag, if present.
                if ((e.State & TreeNodeStates.Focused) != 0)
                {
                    using (Pen focusPen = new Pen(Color.Black))
                    {
                        focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot;
                        Rectangle focusBounds = NodeBounds(e.Node);
                        focusBounds.Size = new Size(focusBounds.Width - 1,
                        focusBounds.Height - 1);
                        e.Graphics.DrawRectangle(focusPen, focusBounds);
                    }
                }
     
            }
            /*   CALCUL DU RECTANGLE DE SELECTION    */
            // Returns the bounds of the specified node, including the region 
            // occupied by the node label and any node tag displayed.
            private Rectangle NodeBounds(TreeNode node)
            {
                // Set the return value to the normal node bounds.
                Rectangle bounds = node.Bounds;
                if (node.Tag != null)
                {
                    // Retrieve a Graphics object from the TreeView handle
                    // and use it to calculate the display width of the tag.
                    Graphics g = treeView1.CreateGraphics();
     
                    // Adjust the node bounds using the calculated value.
     
     
                    //  1- mesure  largeur du node.text suivant 
                    //  le NodeFont utilise & ajuste le rectangle de selection 
     
                    int tagWidth = (int)(g.MeasureString( 
                       node.Text, node.NodeFont).Width);
                    bounds.Width = tagWidth;
     
                    //  2-mesure la largeur d'icon 
                    Icon icn = (Icon)(node.Tag);
                    tagWidth = icn.Width;
     
                    // decale le sommet -x- du  rectangle de selection 
     
                    bounds.Offset(tagWidth / 2, 0);
     
     
                   /* ------ rappel :une dilatation accroit a gauche et à droite simuultanement)....*/ 
                   //   dilate  suivant -x-  de tagWidth / 2  tel que
     
                    bounds = Rectangle.Inflate(bounds, tagWidth / 2, 0);
                    g.Dispose();
                }
     
                return bounds;
     
            }
     
     
     
        }
    }
    bon code...

Discussions similaires

  1. TreeView et menu contextuel...
    Par agh dans le forum Composants VCL
    Réponses: 6
    Dernier message: 06/04/2009, 12h23
  2. Sapin de Noel
    Par dan_marciano dans le forum Algorithmes et structures de données
    Réponses: 20
    Dernier message: 04/01/2009, 15h53
  3. vb.net - Problème Treeview.DrawNode
    Par House MD dans le forum VB.NET
    Réponses: 0
    Dernier message: 06/11/2008, 15h41
  4. [Pointer]Treeview.Data
    Par rbag dans le forum Composants VCL
    Réponses: 7
    Dernier message: 31/08/2002, 01h44

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