2012-04-05 27 views
23

Gretings.C# WinForms làm nổi bật treenode khi treeview không có tiêu điểm

Tôi đang tạo giao diện để chỉnh sửa các tình huống cho trò chơi. Về cơ bản nó bao gồm các sự kiện, trong đó có điều kiện lồng nhau và hành động. Vì vậy, tôi đã lên kế hoạch sử dụng hai lượt xem tre - một để chọn sự kiện và một cho việc chọn điều kiện/hành động bên trong sự kiện để chỉnh sửa.

Bây giờ, bạn thấy, nếu tôi chọn một sự kiện (trong treeview bên trái) và sau đó cố gắng chọn một cái gì đó trong thanh bên phải, thanh bên trái sẽ ngừng hiển thị hình chữ nhật lựa chọn màu xanh lam. Điều này rõ ràng là xấu bởi vì bây giờ người dùng không biết sự kiện nào mà anh ấy đang chỉnh sửa!

Cách duy nhất tôi tìm thấy để giữ lại một số loại thông tin về lựa chọn hiện tại là gì bằng cách sử dụng SelectedImageIndex, nhưng đó chỉ là một hình ảnh nhỏ sẽ khác.

Có cách nào khác để làm nổi bật treenode trong khi không có tiêu điểm trên treeview không? Tôi biết tôi có thể chỉ Graphics.DrawRectangle hoặc một cái gì đó, nhưng tôi nghe nói rằng bản vẽ nên được thực hiện trong sự kiện Paint và treeview không có sự kiện sơn ... Vì vậy, tôi đoán nếu tôi vẽ nó vào trường hợp mất tập trung, và sau đó kéo mẫu ra khỏi màn hình hoặc một cái gì đó, nó sẽ bị "xóa"?

Dù sao, xin vui lòng cho tôi biết nếu bạn có một ý tưởng (khác vì sử dụng một biểu tượng riêng cho lựa chọn và không được chọn TreeNode)

Cảm ơn!

+0

hình ảnh bạn đã đăng đã biến mất. bạn có bản sao ở đâu không? Tôi sẽ xóa liên kết trong thời gian chờ đợi .. –

Trả lời

49

Những gì bạn đang tìm kiếm là thuộc tính HideSelection trên TreeView.

Từ MSDN:

Gets hoặc thiết lập một giá trị chỉ ra liệu các nút cây được lựa chọn vẫn nhấn mạnh ngay cả khi màn hình cây đã mất đi sự tập trung.

Link: http://msdn.microsoft.com/en-us/library/system.windows.forms.treeview.hideselection.aspx

Code:

TreeView.HideSelection = false; 
+12

thực sự trên Windows7 với lược đồ màu mặc định, điều này không có tác dụng - khi treeview mất tiêu điểm thì nút đã chọn sẽ bị bỏ chọn và tôi không thể thấy sự khác biệt từ các nút khác. – oleksa

14

Nó vẫn được hiển thị nhưng chỉ có màu xám nhạt mà tùy thuộc vào màn hình của bạn và thiết lập hiện tại có thể được gần trong có thể nhìn thấy!

Ghi đè sự kiện OnDrawNode. Vì vậy, bạn tạo và lớp mới (gọi nó là "SpecialTreeView") kế thừa từ Microsoft TreeView như class SpecialTreeView : TreeView. Sau đó, bạn thêm ghi đè sự kiện sau:

protected override void OnDrawNode(DrawTreeNodeEventArgs e) 
{ 
    TreeNodeStates treeState = e.State; 
    Font treeFont = e.Node.NodeFont ?? e.Node.TreeView.Font; 

    // Colors. 
    Color foreColor = e.Node.ForeColor; 
    string strDeselectedColor = @"#6B6E77", strSelectedColor = @"#94C7FC"; 
    Color selectedColor = System.Drawing.ColorTranslator.FromHtml(strSelectedColor); 
    Color deselectedColor = System.Drawing.ColorTranslator.FromHtml(strDeselectedColor); 

    // New brush. 
    SolidBrush selectedTreeBrush = new SolidBrush(selectedColor); 
    SolidBrush deselectedTreeBrush = new SolidBrush(deselectedColor); 

    // Set default font color. 
    if (foreColor == Color.Empty) 
     foreColor = e.Node.TreeView.ForeColor; 

    // Draw bounding box and fill. 
    if (e.Node == e.Node.TreeView.SelectedNode) 
    { 
     // Use appropriate brush depending on if the tree has focus. 
     if (this.Focused) 
     { 
      foreColor = SystemColors.HighlightText; 
      e.Graphics.FillRectangle(selectedTreeBrush, e.Bounds); 
      ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight); 
      TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, 
             foreColor, TextFormatFlags.GlyphOverhangPadding); 
     } 
     else 
     { 
      foreColor = SystemColors.HighlightText; 
      e.Graphics.FillRectangle(deselectedTreeBrush, e.Bounds); 
      ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, foreColor, SystemColors.Highlight); 
      TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, 
             foreColor, TextFormatFlags.GlyphOverhangPadding); 
     } 
    } 
    else 
    { 
     if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot) 
     { 
      e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); 
      TextRenderer.DrawText(e.Graphics, e.Node.Text, hotFont, e.Bounds, 
             System.Drawing.Color.Black, TextFormatFlags.GlyphOverhangPadding); 
     } 
     else 
     { 
      e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); 
      TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, 
             foreColor, TextFormatFlags.GlyphOverhangPadding); 
     } 
    } 
} 

Biên dịch mã và bạn sẽ thấy "SpecialTreeView" trong hộp công cụ của bạn trong trình thiết kế. Thay thế TreeView của bạn bằng cái mới này bằng cùng một tên và điều duy nhất sẽ khác nhau là màu lựa chọn. Khi được chọn, nó sẽ là selectedColor, khi không được chọn deselectedColor.

Tôi hy vọng điều này sẽ hữu ích.

+0

Vâng, nó có, nhưng chỉ có nó không :) Trừ khi bạn đặt HideSelection thành false, điều này đúng theo mặc định (cái gì cho? ... eh, doanh nghiệp M $ điển hình). Cảm ơn lời khuyên của bạn anyway, tôi didnt nhận thấy rằng nó có "DrawNode" sự kiện, đang tìm kiếm một sự kiện điển hình Sơn ... – Istrebitel

+0

Huh .... nó .... wont cháy! Tôi đã sử dụng kiểm soát TreeView tùy chỉnh bởi vì cơ sở một không có khả năng kéo-n-thả ... Overriding OnDragDrop, OnDragEnter vv hoạt động ... ghi đè lên một doesnt này. Nó chỉ không thực hiện, tôi đã đặt một breakpoint - không có gì. Điều gì có thể sai? – Istrebitel

+1

Ah yep, đã tìm thấy nó. DrawMode của nó, nếu nó được đặt thành Normal thì sự kiện sẽ không cháy. – Istrebitel

7

Không giải pháp hoàn toàn hoàn hảo, nhưng khá gần:

treeView.HideSelection = false; 
treeView.DrawMode = TreeViewDrawMode.OwnerDrawText; 
treeView.DrawNode += (o, e) => 
{ 
    if (!e.Node.TreeView.Focused && e.Node == e.Node.TreeView.SelectedNode) 
    { 
     Font treeFont = e.Node.NodeFont ?? e.Node.TreeView.Font; 
     e.Graphics.FillRectangle(Brushes.Gray, e.Bounds); 
     ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, SystemColors.HighlightText, SystemColors.Highlight); 
     TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, SystemColors.HighlightText, TextFormatFlags.GlyphOverhangPadding); 
    } 
    else 
     e.DrawDefault = true; 
}; 
treeView.MouseDown += (o, e) => 
{ 
    TreeNode node = treeView.GetNodeAt(e.X, e.Y); 
    if (node != null && node.Bounds.Contains(e.X, e.Y)) 
     treeView.SelectedNode = node; 
}; 
+1

Cảm ơn, điều này đã giúp. Mặc dù tôi đã thay đổi Brushes.Gray thành SystemBrushes.Highlight – GeoffCoope

9

nhanh giải pháp:

Đặt các thuộc tính:

  • HideSelection = false;
  • DrawMode = TreeViewDrawMode.OwnerDrawText;

Sau đó, trong xử lý sự kiện DrawNode chỉ cần làm:

private void treeView1_DrawNode(object sender, DrawTreeNodeEventArgs e) { 
    e.DrawDefault = true; 
} 

On Windwos 7 này khôi phục các rendering cũ, bao gồm hộp tiêu tan xung quanh vùng chọn (mà thực sự trông hơi bị lỗi thời). Văn bản sẽ có màu trắng với tiêu điểm và màu đen không có tiêu điểm. Nền màu xanh và hiển thị.

Câu trả lời này không phải là mới, các câu trả lời khác cũng chứa các bước này, nhưng đây là yêu cầu tối thiểu (ít nhất là trong Windows 7, không kiểm tra hệ điều hành khác).

+0

Tôi thích ngoại trừ hai vấn đề: 1) Biểu tượng hộp kiểm bị cắt ở bên phải và 2) có vẻ chậm hơn đáng kể khi kiểm tra/bỏ chọn .... – AndrewRalon

Các vấn đề liên quan