TreeView.DrawNode Gebeurtenis

Definitie

Treedt op wanneer een TreeView teken wordt getekend en de DrawMode eigenschap is ingesteld op een TreeViewDrawMode andere waarde dan Normal.

public:
 event System::Windows::Forms::DrawTreeNodeEventHandler ^ DrawNode;
public event System.Windows.Forms.DrawTreeNodeEventHandler DrawNode;
public event System.Windows.Forms.DrawTreeNodeEventHandler? DrawNode;
member this.DrawNode : System.Windows.Forms.DrawTreeNodeEventHandler 
Public Custom Event DrawNode As DrawTreeNodeEventHandler 

Gebeurtenistype

Voorbeelden

In het volgende codevoorbeeld ziet u hoe u een TreeView besturingselement aanpast met behulp van een eigenaartekening. In TreeView het besturingselement in het voorbeeld worden optionele knooppunttags naast de standaardknooppuntlabels weergegeven. Knooppunttags worden opgegeven met behulp van de TreeNode.Tag eigenschap. Het TreeView besturingselement maakt ook gebruik van aangepaste kleuren, waaronder een aangepaste markeringskleur.

U kunt de TreeView meeste kleuren aanpassen door kleureigenschappen in te stellen, maar de kleur van de selectiemarkering is niet beschikbaar als eigenschap. Bovendien wordt de standaardrechthoek met selectiemarkeringen alleen rond een knooppuntlabel uitgebreid. Eigenaartekening moet worden gebruikt om de knooppunttags te tekenen en om een aangepaste markeringsrechthoek te tekenen die groot genoeg is om een knooppunttag op te nemen.

In het voorbeeld tekent een handler voor de DrawNode gebeurtenis de knooppunttags en de aangepaste selectiemarkering handmatig. Niet-geselecteerde knooppunten hebben geen aanpassing nodig. Hiervoor wordt de DrawTreeNodeEventArgs.DrawDefault eigenschap zo ingesteld true dat ze door het besturingssysteem worden getekend.

Daarnaast biedt een handler voor de MouseDown gebeurtenis hit-testing. Standaard kan een knooppunt alleen worden geselecteerd door op de regio rond het label te klikken. De MouseDown gebeurtenis-handler selecteert een knooppunt waarop ergens in deze regio of in de regio rond een knooppunttag wordt geklikt, indien aanwezig.

#using <System.dll>
#using <System.Windows.Forms.dll>
#using <System.Drawing.dll>

using namespace System;
using namespace System::Drawing;
using namespace System::Windows::Forms;
public ref class TreeViewOwnerDraw: public Form
{
private:
   TreeView^ myTreeView;

   // Create a Font object for the node tags.
   System::Drawing::Font^ tagFont;

public:

   TreeViewOwnerDraw()
   {
      tagFont = gcnew System::Drawing::Font( "Helvetica",8,FontStyle::Bold );

      // Create and initialize the TreeView control.
      myTreeView = gcnew TreeView;
      myTreeView->Dock = DockStyle::Fill;
      myTreeView->BackColor = Color::Tan;
      myTreeView->CheckBoxes = true;
      
      // Add nodes to the TreeView control.
      TreeNode^ node;
      for ( int x = 1; x < 4; ++x )
      {
         // Add a root node to the TreeView control.
         node = myTreeView->Nodes->Add( String::Format( "Task {0}", x ) );
         for ( int y = 1; y < 4; ++y )
         {
            // Add a child node to the root node.
            node->Nodes->Add( String::Format( "Subtask {0}", y ) );
         }
      }
      myTreeView->ExpandAll();
      
      // Add tags containing alert messages to a few nodes 
      // and set the node background color to highlight them.
      myTreeView->Nodes[ 1 ]->Nodes[ 0 ]->Tag = "urgent!";
      myTreeView->Nodes[ 1 ]->Nodes[ 0 ]->BackColor = Color::Yellow;
      myTreeView->SelectedNode = myTreeView->Nodes[ 1 ]->Nodes[ 0 ];
      myTreeView->Nodes[ 2 ]->Nodes[ 1 ]->Tag = "urgent!";
      myTreeView->Nodes[ 2 ]->Nodes[ 1 ]->BackColor = Color::Yellow;
      
      // Configure the TreeView control for owner-draw and add
      // a handler for the DrawNode event.
      myTreeView->DrawMode = TreeViewDrawMode::OwnerDrawText;
      myTreeView->DrawNode += gcnew DrawTreeNodeEventHandler( this, &TreeViewOwnerDraw::myTreeView_DrawNode );
      
      // Add a handler for the MouseDown event so that a node can be 
      // selected by clicking the tag text as well as the node text.
      myTreeView->MouseDown += gcnew MouseEventHandler( this, &TreeViewOwnerDraw::myTreeView_MouseDown );
      
      // Initialize the form and add the TreeView control to it.
      this->ClientSize = System::Drawing::Size( 292, 273 );
      this->Controls->Add( myTreeView );
   }

protected:
   // Clean up any resources being used.        
   ~TreeViewOwnerDraw()
   {
      if ( tagFont != nullptr )
      {
         delete tagFont;
      }
   }

   // Draws a node.
private:
   void myTreeView_DrawNode( Object^ sender, DrawTreeNodeEventArgs^ e )
   {
      // Draw the background and node text for a selected node.
      if ( (e->State & TreeNodeStates::Selected) != (TreeNodeStates)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 ) );

         // Retrieve the node font. If the node font has not been set,
         // use the TreeView font.
         System::Drawing::Font^ nodeFont = e->Node->NodeFont;
         if ( nodeFont == nullptr )
                  nodeFont = (dynamic_cast<TreeView^>(sender))->Font;

         // Draw the node text.
         e->Graphics->DrawString( e->Node->Text, 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 string representation 
      // to the right of the label text.
      if ( e->Node->Tag != nullptr )
      {
         e->Graphics->DrawString( e->Node->Tag->ToString(), tagFont, Brushes::Yellow, (float)e->Bounds.Right + 2, (float)e->Bounds.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) != (TreeNodeStates)0 )
      {
         Pen^ focusPen = gcnew Pen( Color::Black );
         try
         {
            focusPen->DashStyle = System::Drawing::Drawing2D::DashStyle::Dot;
            Rectangle focusBounds = NodeBounds( e->Node );
            focusBounds.Size = System::Drawing::Size( focusBounds.Width - 1, focusBounds.Height - 1 );
            e->Graphics->DrawRectangle( focusPen, focusBounds );
         }
         finally
         {
            if ( focusPen )
               delete safe_cast<IDisposable^>(focusPen);
         }

      }
   }

   // Selects a node that is clicked on its label or tag text.
   void myTreeView_MouseDown( Object^ /*sender*/, MouseEventArgs^ e )
   {
      TreeNode^ clickedNode = myTreeView->GetNodeAt( e->X, e->Y );
      if ( NodeBounds( clickedNode ).Contains( e->X, e->Y ) )
      {
         myTreeView->SelectedNode = clickedNode;
      }
   }

   // Returns the bounds of the specified node, including the region 
   // occupied by the node label and any node tag displayed.
   Rectangle NodeBounds( TreeNode^ node )
   {
      // Set the return value to the normal node bounds.
      Rectangle bounds = node->Bounds;
      if ( node->Tag != nullptr )
      {
         // Retrieve a Graphics object from the TreeView handle
         // and use it to calculate the display width of the tag.
         Graphics^ g = myTreeView->CreateGraphics();
         int tagWidth = (int)g->MeasureString( node->Tag->ToString(), tagFont ).Width + 6;
         
         // Adjust the node bounds using the calculated value.
         bounds.Offset( tagWidth / 2, 0 );
         bounds = Rectangle::Inflate( bounds, tagWidth / 2, 0 );
         g->~Graphics();
      }

      return bounds;
   }
};

[STAThreadAttribute]
int main()
{
   Application::Run( gcnew TreeViewOwnerDraw );
}
using System;
using System.Drawing;
using System.Windows.Forms;

public class TreeViewOwnerDraw : Form
{
    private TreeView myTreeView;

    // Create a Font object for the node tags.
    Font tagFont = new Font("Helvetica", 8, FontStyle.Bold);

    public TreeViewOwnerDraw()
    {
        // Create and initialize the TreeView control.
        myTreeView = new TreeView();
        myTreeView.Dock = DockStyle.Fill;
        myTreeView.BackColor = Color.Tan;
        myTreeView.CheckBoxes = true;

        // Add nodes to the TreeView control.
        TreeNode node;
        for (int x = 1; x < 4; ++x)
        {
            // Add a root node to the TreeView control.
            node = myTreeView.Nodes.Add(String.Format("Task {0}", x));
            for (int y = 1; y < 4; ++y)
            {
                // Add a child node to the root node.
                node.Nodes.Add(String.Format("Subtask {0}", y));
            }
        }
        myTreeView.ExpandAll();

        // Add tags containing alert messages to a few nodes 
        // and set the node background color to highlight them.
        myTreeView.Nodes[1].Nodes[0].Tag = "urgent!";
        myTreeView.Nodes[1].Nodes[0].BackColor = Color.Yellow;
        myTreeView.SelectedNode = myTreeView.Nodes[1].Nodes[0];
        myTreeView.Nodes[2].Nodes[1].Tag = "urgent!";
        myTreeView.Nodes[2].Nodes[1].BackColor = Color.Yellow;

        // Configure the TreeView control for owner-draw and add
        // a handler for the DrawNode event.
        myTreeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
        myTreeView.DrawNode += 
            new DrawTreeNodeEventHandler(myTreeView_DrawNode);

        // Add a handler for the MouseDown event so that a node can be 
        // selected by clicking the tag text as well as the node text.
        myTreeView.MouseDown += new MouseEventHandler(myTreeView_MouseDown);

        // Initialize the form and add the TreeView control to it.
        this.ClientSize = new Size(292, 273);
        this.Controls.Add(myTreeView);
    }

    // Clean up any resources being used.        
    protected override void Dispose(bool disposing)
    {
        if (disposing)
        {
            tagFont.Dispose();
        }
        base.Dispose(disposing);
    }

    [STAThreadAttribute()]
    static void Main() 
    {
        Application.Run(new TreeViewOwnerDraw());
    }

    // Draws a node.
    private void myTreeView_DrawNode(
        object sender, DrawTreeNodeEventArgs e)
    {
        // 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));

            // Retrieve the node font. If the node font has not been set,
            // use the TreeView font.
            Font nodeFont = e.Node.NodeFont;
            if (nodeFont == null) nodeFont = ((TreeView)sender).Font;

            // Draw the node text.
            e.Graphics.DrawString(e.Node.Text, 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 string representation 
        // to the right of the label text.
        if (e.Node.Tag != null)
        {
            e.Graphics.DrawString(e.Node.Tag.ToString(), tagFont,
                Brushes.Yellow, e.Bounds.Right + 2, e.Bounds.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);
            }
        }
    }

    // Selects a node that is clicked on its label or tag text.
    private void myTreeView_MouseDown(object sender, MouseEventArgs e)
    {
        TreeNode clickedNode = myTreeView.GetNodeAt(e.X, e.Y);
        if (NodeBounds(clickedNode).Contains(e.X, e.Y))
        {
            myTreeView.SelectedNode = clickedNode;
        }
    }

    // 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 = myTreeView.CreateGraphics(); 
            int tagWidth = (int)g.MeasureString
                (node.Tag.ToString(), tagFont).Width + 6;

            // Adjust the node bounds using the calculated value.
            bounds.Offset(tagWidth/2, 0);
            bounds = Rectangle.Inflate(bounds, tagWidth/2, 0);
            g.Dispose();
         }
        
        return bounds;
    }
}
Imports System.Drawing
Imports System.Windows.Forms

Public Class TreeViewOwnerDraw
    Inherits Form

    Private WithEvents myTreeView As TreeView
    
    ' Create a Font object for the node tags.
    Private tagFont As New Font("Helvetica", 8, FontStyle.Bold)
    
    Public Sub New()

        ' Create and initialize the TreeView control.
        myTreeView = New TreeView()
        myTreeView.Dock = DockStyle.Fill
        myTreeView.BackColor = Color.Tan
        myTreeView.CheckBoxes = True
        
        ' Add nodes to the TreeView control.
        Dim node As TreeNode
        Dim x As Integer
        For x = 1 To 3

            ' Add a root node to the TreeView control.
            node = myTreeView.Nodes.Add(String.Format("Task {0}", x))
            Dim y As Integer
            For y = 1 To 3 

                ' Add a child node to the root node.
                node.Nodes.Add(String.Format("Subtask {0}", y))
            Next y
        Next x
        myTreeView.ExpandAll()
        
        ' Add tags containing alert messages to a few nodes 
        ' and set the node background color to highlight them.
        myTreeView.Nodes(1).Nodes(0).Tag = "urgent!"
        myTreeView.Nodes(1).Nodes(0).BackColor = Color.Yellow
        myTreeView.SelectedNode = myTreeView.Nodes(1).Nodes(0)
        myTreeView.Nodes(2).Nodes(1).Tag = "urgent!"
        myTreeView.Nodes(2).Nodes(1).BackColor = Color.Yellow
        
        ' Configure the TreeView control for owner-draw.
        myTreeView.DrawMode = TreeViewDrawMode.OwnerDrawText

        ' Add a handler for the MouseDown event so that a node can be 
        ' selected by clicking the tag text as well as the node text.
        AddHandler myTreeView.MouseDown, AddressOf myTreeView_MouseDown
        
        ' Initialize the form and add the TreeView control to it.
        Me.ClientSize = New Size(292, 273)
        Me.Controls.Add(myTreeView)
    End Sub
    
    <STAThreadAttribute()> _
    Shared Sub Main()
        Application.Run(New TreeViewOwnerDraw())
    End Sub
    
    ' Draws a node.
    Private Sub myTreeView_DrawNode(ByVal sender As Object, _
        ByVal e As DrawTreeNodeEventArgs) Handles myTreeView.DrawNode

        ' 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 text of a node tag, if one is present.
            e.Graphics.FillRectangle(Brushes.Green, NodeBounds(e.Node))

            ' Retrieve the node font. If the node font has not been set,
            ' use the TreeView font.
            Dim nodeFont As Font = e.Node.NodeFont
            If nodeFont Is Nothing Then
                nodeFont = CType(sender, TreeView).Font
            End If

            ' Draw the node text.
            e.Graphics.DrawString(e.Node.Text, nodeFont, Brushes.White, _
                e.Bounds.Left - 2, e.Bounds.Top)

        ' Use the default background and node text.
        Else
            e.DrawDefault = True
        End If

        ' If a node tag is present, draw its string representation 
        ' to the right of the label text.
        If (e.Node.Tag IsNot Nothing) Then
            e.Graphics.DrawString(e.Node.Tag.ToString(), tagFont, _
                Brushes.Yellow, e.Bounds.Right + 2, e.Bounds.Top)
        End If

        ' 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 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

    ' Selects a node that is clicked on its label or tag text.
    Private Sub myTreeView_MouseDown(ByVal sender As Object, ByVal e As MouseEventArgs)
        Dim clickedNode As TreeNode = myTreeView.GetNodeAt(e.X, e.Y)
        If NodeBounds(clickedNode).Contains(e.X, e.Y) Then
            myTreeView.SelectedNode = clickedNode
        End If
    End Sub

    ' 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 = myTreeView.CreateGraphics()
            Dim tagWidth As Integer = CInt(g.MeasureString( _
                node.Tag.ToString(), tagFont).Width) + 6

            ' Adjust the node bounds using the calculated value.
            bounds.Offset(tagWidth \ 2, 0)
            bounds = Rectangle.Inflate(bounds, tagWidth \ 2, 0)
            g.Dispose()
        End If
        Return bounds
    End Function 'NodeBounds

End Class

Opmerkingen

Gebruik deze gebeurtenis om het uiterlijk van knooppunten in een TreeView besturingselement aan te passen met behulp van een eigenaartekening.

Deze gebeurtenis wordt alleen gegenereerd wanneer de DrawMode eigenschap is ingesteld op TreeViewDrawMode waarden van OwnerDrawAll of OwnerDrawText. De volgende tabel geeft aan hoe de TreeNode eigenschap kan worden aangepast wanneer de DrawMode eigenschap is ingesteld op deze waarden.

Waarde van de eigenschap DrawMode TreeNode-aanpassing
OwnerDrawText Het TreeNode labelgebied kan worden aangepast. Alle andere TreeNode elementen worden automatisch getekend.
OwnerDrawAll Het uiterlijk van het geheel TreeNode kan worden aangepast. Pictogrammen, selectievakjes, plus- en mintekens en lijnen die de knooppunten verbinden, moeten handmatig worden getekend, indien gewenst.

De regio die de waarde zou innemen als deze TreeNode.Text is getekend met behulp van het lettertype dat is opgegeven door de eigenschap van TreeView het Font besturingselement, is de regio waarin een knooppunt kan worden geklikt om deze te selecteren. Dit wordt de hittestregio genoemd. Als u buiten deze regio tekent, moet u uw eigen code opgeven waarmee een knooppunt wordt geselecteerd wanneer het zichtbare gebied wordt geklikt.

De hittestregio komt overeen met de DrawTreeNodeEventArgs.Bounds eigenschap wanneer u deze gebruikt OwnerDrawText. Wanneer u OwnerDrawAllechter de eigenschap gebruikt, omvat de DrawTreeNodeEventArgs.Bounds gehele breedte van het TreeView. In dit geval hebt u toegang tot de hittestregio door de waarde op te halen en de DrawTreeNodeEventArgs.Node eigenschap ervan te TreeNode.Bounds openen. U kunt vervolgens de testregio van het treffergebied van het knooppunt binnen deze grenzen tekenen of u kunt uw eigen hittestcode opgeven. Houd er rekening mee dat het instellen van de TreeNode.NodeFont eigenschap de grootte van het treffertestgebied niet wijzigt, wat wordt berekend met behulp van het lettertype dat is opgegeven voor het hele TreeView.

Zie Gebeurtenissen verwerken en genereren voor meer informatie over het afhandelen van gebeurtenissen.

Van toepassing op

Zie ook