2012-01-09 2 views
2

У меня возникли проблемы со стандартным Windows Forms TreeView; в частности, с цветом, с которым элемент управления по умолчанию использовался для рендеринга выбранного узла, когда древовидный вид не имел фокуса. Это был светло-серый цвет, который на некоторых экранах был почти невидимым. Впоследствии я подклассифицировал TreeView и переопределил событие TreeView OnDrawNode, чтобы покрасить мои узлы по своему желанию. Это работает хорошо, но теперь «HotTracking» (активное выделение, когда мышь находится над данным узлом дерева) перегружается моим пользовательским событием OnDrawNode. Я не очень хорошо знаком с классами Graphics и задался вопросом, как я могу изменить текущий подкласс, включив в него горячее отслеживание? Я знаю, что могу использовать e.Graphics.DrawLine(Pen pen, Point p1, Point p2);, но это будет беспорядочно, есть ли более простой способ?Правильное отображение переопределенного TreeView

Вот существующий код:

class CustomTreeView : TreeView 
{ 
    public CustomTreeView() 
    { 
     this.DrawMode = TreeViewDrawMode.OwnerDrawText; 
    } 

    // Override the drawMode of TreeView. 
    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"; //@"#1ABEE8"; //@"#2FC0EE"; //@"#3A8FEA"; 
     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 /*SystemBrushes.Highlight*/, 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 /*SystemBrushes.Highlight*/, 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 
     { 
      // This is firing but is being over written, perhaps by the above? 
      if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot) 
      { 
       e.DrawDefault = true; 
       e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); 
       TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, System.Drawing.Color.Blue, TextFormatFlags.GlyphOverhangPadding); 
      } 
      else 
      { 
       e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds); 
       TextRenderer.DrawText(e.Graphics, e.Node.Text, treeFont, e.Bounds, foreColor, TextFormatFlags.GlyphOverhangPadding); 
      } 
     } 
    } 

Как всегда, ребята, большое спасибо за ваше время.

+0

* «Это был светло-серый цвет, который на некоторых экранах был почти невидим». * Так что компьютер этого человека в основном непригодный для использования, не так ли? Поскольку Windows использует тот же самый неактивный цвет подсветки во всей системе и во всех других приложениях. Надеюсь, это киоск-машина, которая запускает * только * ваше приложение, иначе бесполезно его менять. И я не рекомендую менять его в любом случае, потому что, как вы заметили, рисунок владельца делает все намного сложнее. В этом случае вам нужно будет добавить код к методам обработчика событий мыши, чтобы самому выполнить горячее отслеживание. Это не будет автоматически. –

+0

Почему это 'тщетно', чтобы изменить его? На белом фоне этот неактивный цвет подсветки очень слабый серый, и в некоторых случаях это не легко увидеть (например, проблема, которую я описываю для treeView выше). Обработчик событий мыши («MouseMove» или какое-то подобное событие), который имеет дело с «HotTracking», скорее всего, будет вызывать событие OnDrawNode для рендеринга узлов - вопрос все еще стоит. Как лучше всего реализовать функциональность «HotTracking». Спасибо за ваше время ... – MoonKnight

ответ

5

Вы должны обратить внимание на e.State в своем коде. Свойство DrawTreeNodeEventArgs.State сообщает вам, что происходит с узлом, соответственно выбирайте цвета. Также ознакомьтесь с примером библиотеки MSDN, указанным в документах для TreeNode.DrawNode.

+0

Большое спасибо за ваше время. – MoonKnight

+0

Hans, теперь я проверяю выбранный узел. Если он не выбран, я проверяю, находится ли мышь над узлом usng 'if ((e.State & TreeNodeStates.Hot) == TreeNodeStates.Hot)', тогда я пытаюсь потянуть текст по-другому. Он ударяет по этому коду, но, похоже, не выполняет его. Можете ли вы дать мне другие рекомендации? Я поместил код выше, чтобы показать, что я пытался. Еще раз спасибо ... – MoonKnight

+2

Почему вы устанавливаете e.DrawDefault = true? Это передержет любую картину, которую вы сделали. –

0

Просто установите HotTracking из дерева TreeView в true, и он будет работать, потому что в TreeView узлы, которые он содержит, не имеют самоидентификации, поскольку каждый элемент управления является draw by TreeView, а узлы просто содержат данные, поэтому у них нет событий, и TreeView выполняет всю работу, поэтому, чтобы установить эти горячие статусы

objTreeView.HotTracking = true;

TreeView начнет предоставлять вам статус, и ваш код будет работать нормально.

Смежные вопросы