다음을 통해 공유


TreeView.DrawNode 이벤트

정의

TreeView가 그려지고 DrawMode 속성이 Normal이 아닌 TreeViewDrawMode 값으로 설정되면 발생합니다.

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 

이벤트 유형

예제

다음 코드 예제에는 사용자 지정 하는 방법을 보여 줍니다.는 TreeView 소유자 그리기를 사용 하 여 제어 합니다. TreeView 예제에서 컨트롤 표준 노드 레이블와 함께 선택적 노드 태그를 표시 합니다. 노드 태그는 속성을 사용하여 TreeNode.Tag 지정됩니다. 컨트롤은 TreeView 사용자 지정 강조 색을 포함하는 사용자 지정 색도 사용합니다.

대부분의 사용자 지정할 수 있습니다는 TreeView 색 속성을 설정 하 여 색 있지만 선택 강조 색 속성으로 사용할 수 없습니다. 또한 노드 레이블 주위에 기본 선택 항목 강조 표시 사각형을 확장합니다. 소유자 그리기는 노드 태그를 그릴 및 노드 태그를 포함 하도록 충분히 큰 사용자 지정된 강조 표시 사각형을 그리려면 사용 되어야 합니다.

예에 대 한 처리기를 DrawNode 노드 태그 및 사용자 지정 선택 수동으로 강조 표시 하는 이벤트 그립니다. 선택 되지 않은 노드는 사용자 지정할이 필요가 없습니다. 이러한 경우는 DrawTreeNodeEventArgs.DrawDefault 속성이 true 운영 체제에서 그려질 수 있도록 합니다.

또한 처리기는 MouseDown 이벤트 적중 테스트를 제공 합니다. 기본적으로 노드는 레이블 주위의 영역을 클릭 해 서만 선택할 수 있습니다. MouseDown 이벤트 처리기는 있는 경우이 지역 내에서 또는 노드 태그 주변 지역 내에서 아무 곳 이나 클릭 되는 노드를 선택 합니다.

#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

설명

이 이벤트를 사용 하 여 노드의 모양을 사용자 지정 하는 TreeView 소유자 그리기를 사용 하 여 제어 합니다.

이 이벤트는 속성이 또는 OwnerDrawTextOwnerDrawAll 으로 TreeViewDrawMode 설정된 경우에만 DrawMode 발생합니다. 다음 표에서는 속성을 이러한 값으로 TreeNode 설정할 때 DrawMode 를 사용자 지정할 수 있는 방법을 나타냅니다.

DrawMode 속성 값 TreeNode 사용자 지정
OwnerDrawText TreeNode 레이블 영역을 사용자 지정할 수 있습니다. 다른 TreeNode 모든 요소는 자동으로 그려집니다.
OwnerDrawAll 전체 TreeNode 모양을 사용자 지정할 수 있습니다. 원하는 경우 아이콘, 검사 상자 및 빼기 기호 및 노드를 연결하는 줄을 수동으로 그려야 합니다.

컨트롤 Font 의 속성에 TreeNode.Text 지정된 TreeView 글꼴을 사용하여 그리는 경우 값이 차지하는 영역은 노드를 클릭하여 선택할 수 있는 영역입니다. 이를 적중 테스트 지역이라고 합니다. 이 지역 외부에서 그리는 경우 표시되는 영역을 클릭할 때 노드를 선택하는 고유한 코드를 제공해야 합니다.

적중 테스트 지역은 를 사용할 OwnerDrawText때 속성에 DrawTreeNodeEventArgs.Bounds 해당합니다. 그러나 를 사용하는 OwnerDrawAll경우 속성은 DrawTreeNodeEventArgs.Bounds 의 전체 너비를 TreeView포함합니다. 이 경우 값을 가져오 DrawTreeNodeEventArgs.Node 고 해당 TreeNode.Bounds 속성에 액세스하여 적중 테스트 지역에 액세스할 수 있습니다. 그런 다음 노드의 적중 테스트 영역을 이러한 범위 내에 그리거나 고유한 적중 테스트 코드를 제공할 수 있습니다. 속성 설정 TreeNode.NodeFont 은 전체 TreeView에 지정된 글꼴을 사용하여 계산되는 적중 테스트 영역의 크기를 변경하지 않습니다.

이벤트를 처리 하는 방법에 대 한 자세한 내용은 참조 하세요. 이벤트 처리 및 발생합니다.

적용 대상

추가 정보