2010-01-12 41 views
8

Tôi có một ứng dụng được kết nối với máy chủ từ xa và dữ liệu thăm dò ý kiến ​​khi cần. Nó có một TreeView nơi các nút biểu diễn các đối tượng có sẵn và màu sắc của văn bản cho biết liệu dữ liệu đã được nạp hay chưa; màu xám-in nghiêng cho biết không được tải, màu đen, văn bản thông thường được tải.Sự cố với TreeView.DrawNode - OwnerDrawText

Hiện nay tôi đã thiết lập các TreeView để được OwnderDrawText và có chức năng TreeView.DrawNode chỉ cần vẽ các văn bản như vậy:

private void TreeViewDrawNode(object sender, DrawTreeNodeEventArgs e) 
{ 
    if (!e.Node.IsVisible) 
    { 
     return; 
    } 

    bool bLoaded = false; 

    if (e.Bounds.Location.X >= 0 && e.Bounds.Location.Y >= 0) 
    { 
     if(e.Node.Tag != null) 
     { 
      //... 
      // code determining whether data has been loaded is done here 
      // setting bLoaded true or false 
      //... 
     } 
     else 
     { 
      e.DrawDefault = true; 
      return; 
     } 

     Font useFont = null; 
     Brush useBrush = null; 

     if (bLoaded) 
     { 
      useFont = e.Node.TreeView.Font; 
      useBrush = SystemBrushes.WindowText; 
     } 
     else 
     { 
      useFont = m_grayItallicFont; 
      useBrush = SystemBrushes.GrayText; 
     } 
     e.Graphics.DrawString(e.Node.Text, useFont, useBrush, e.Bounds.Location); 
    } 
} 

I figured rằng sẽ là đủ, tuy nhiên, điều này đã gây ra một số vấn đề;

  1. Khi nút được chọn, tập trung hay không, nó không bao bọc tất cả văn bản, example (Tôi hy vọng là đúng).
  2. Khi nút được lấy nét, đường viền chấm chấm không hiển thị. Nếu bạn so sánh nó với số example này. Các nút có "nhật ký" trong văn bản đang sử dụng e.DefaultDraw = true

Tôi đã thử làm theo ví dụ được đưa ra trong câu hỏi this. Nó trông giống như sau:

private void TreeViewDrawNode(object sender, DrawTreeNodeEventArgs e) 
{ 
    if (!e.Node.IsVisible) 
    { 
    return; 
    } 

    bool bLoaded = false; 

    if (e.Bounds.Location.X >= 0 && e.Bounds.Location.Y >= 0) 
    { 
    if(e.Node.Tag != null) 
    { 
     //... 
     // code determining whether data has been loaded is done here 
     // setting bLoaded true or false 
     //... 
    } 
    else 
    { 
     e.DrawDefault = true; 
     return; 
    } 

    //Select the font and brush depending on whether the property has been loaded 
    Font useFont = null; 
    Brush useBrush = null; 

    if (bLoaded) 
    { 
    useFont = e.Node.TreeView.Font; 
    useBrush = SystemBrushes.WindowText; 
    } 
    else 
    { 
    //member variable defined elsewhere 
    useFont = m_grayItallicFont; 
    useBrush = SystemBrushes.GrayText; 
    } 

    //Begin drawing of the text 

    //Get the rectangle that will be used to draw 
    Rectangle itemRect = e.Bounds; 
    //Move the rectangle over by 1 so it isn't on top of the check box 
    itemRect.X += 1; 

    //Figure out the text position 
    Point textStartPos = new Point(itemRect.Left, itemRect.Top); 
    Point textPos = new Point(textStartPos.X, textStartPos.Y); 

    //generate the text rectangle 
    Rectangle textRect = new Rectangle(textPos.X, textPos.Y, itemRect.Right - textPos.X, itemRect.Bottom - textPos.Y); 

    int textHeight = (int)e.Graphics.MeasureString(e.Node.Text, useFont).Height; 
    int textWidth = (int)e.Graphics.MeasureString(e.Node.Text, useFont).Width; 

    textRect.Height = textHeight; 

    //Draw the highlighted box 
    if ((e.State & TreeNodeStates.Selected) != 0) 
    { 
    //e.Graphics.FillRectangle(SystemBrushes.Highlight, textRect); 
    //use pink to see the difference 
    e.Graphics.FillRectangle(Brushes.Pink, textRect); 
    } 
    //widen the rectangle by 3 pixels, otherwise all of the text  won't fit 
    textRect.Width = textWidth + 3; 

    //actually draw the text 
    e.Graphics.DrawString(e.Node.Text, useFont, useBrush, e.Bounds.Location); 

    //Draw the box around the focused node 
    if ((e.State & TreeNodeStates.Focused) != 0) 
    { 
    textRect.Width = textWidth; 
    Pen focusPen = new Pen(Color.Black); 
    focusPen.DashStyle = System.Drawing.Drawing2D.DashStyle.Dot; 
    e.Graphics.DrawRectangle(focusPen, textRect); 
    } 
    } 
} 

Tuy nhiên, kết quả là this. (Lưu ý, sử dụng màu hồng để phân biệt màu sắc). Như bạn có thể thấy, nền được đánh dấu không mở rộng tất cả các đường đến vị trí của đường chấm chấm tiêu điểm. Và cũng có một hộp khác cũng được vẽ.

Tôi hơi bối rối về cách khắc phục điều này. Tất cả những gì tôi muốn là có văn bản in nghiêng màu xám khi có thứ gì đó được tải. Cách tiếp cận đầu tiên và đơn giản nhất không hoạt động tốt và phương pháp thứ hai cảm thấy như tôi đang làm quá nhiều.

Sau tất cả những điều đó, có ai có bất kỳ đề xuất nào về cách thực hiện điều này đúng cách không, vì đó là cách đơn giản hơn.

Cảm ơn bạn trước.

+0

Cảm ơn bạn rất nhiều vì đã trả về 'if (! E.Node.IsVisible); 'Tôi có rất nhiều vấn đề mà không có nó! – Daywalker

Trả lời

14

Bạn sẽ cần sử dụng TextRenderer.DrawText(). Đó là những gì TreeView sử dụng, nó làm cho văn bản hơi khác so với Graphics.DrawString().

+1

Tất nhiên nó sẽ dễ dàng! Điều đó hoàn toàn làm việc, cảm ơn bạn rất nhiều. Bây giờ, tôi có thể tìm thông tin này về TreeView bằng cách sử dụng DrawText ở đâu? –

+2

Điều này vẫn không sửa tất cả các trục trặc đồ họa. Ngay cả khi trình xử lý DrawNode của tôi vừa đặt DrawDefault thành true và trả về ngay lập tức, nó vẫn gây ra tàn dư của nền hình chữ nhật lựa chọn vẫn còn sau khi nút được bỏ chọn. Ngoài ra, văn bản là tắt trung tâm (theo chiều dọc) khi sử dụng DrawMode = OwnerDrawText, ngay cả khi DrawDefault là tất cả những gì được sử dụng. Nó cần phải được dịch chuyển xuống một pixel để khớp với những gì được hiển thị khi DrawMode = Normal. Vấn đề là các phương thức vẽ của điều khiển là sự kết hợp giữa mã bản vẽ của cửa sổ bản địa và mã bản vẽ khung, và chúng rất không nhất quán. – Triynko