2012-04-05 12 views
23

Gretings.C# WinForms evidenziate treenode quando la visualizzazione ad albero non ha lo stato attivo

Sto creando un'interfaccia per modificare gli scenari di un gioco. Fondamentalmente consiste di eventi, che hanno condizioni e azioni annidate. Quindi, ho pianificato di utilizzare due visualizzazioni di tre: una per selezionare l'evento e un'altra per selezionare la condizione/azione all'interno dell'evento da modificare.

Ora, vedete, se seleziono un evento (nella vista ad albero di sinistra) e poi provate a selezionare qualcosa nella vista ad albero destra, la vista ad albero a sinistra smetterà di mostrare il rettangolo di selezione blu. Questo è ovviamente negativo perché ora l'utente non sa quale evento sta modificando!

L'unico modo in cui ho trovato di conservare una sorta di informazioni su ciò che è la selezione corrente è utilizzando SelectedImageIndex, ma questa è solo una piccola immagine che sarà diversa.

C'è un altro modo per evidenziare il treenode mentre non è attivo il treeview? So che posso solo Graphics.DrawRectangle o qualcosa del genere, ma ho sentito che il disegno dovrebbe essere fatto in Paint event e treeview non ha alcun evento paint ... Quindi suppongo che se lo disegno sull'evento di perdere lo stato attivo, e quindi trascino il modulo fuori dallo schermo o qualcosa del genere, sarà "cancellato"?

In ogni caso, la prego di dirmi se hai un'idea (tranne usando un'icona separata per selezionato e non selezionato TreeNode)

Grazie!

+0

l'immagine che hai postato è sparita. hai una copia da qualche parte? nel frattempo rimuoverò il collegamento .. –

risposta

49

Quello che stai cercando è la proprietà HideSelection su TreeView.

Da MSDN:

Ottiene o imposta un valore che indica se il nodo dell'albero selezionato rimane evidenziato anche quando la visualizzazione albero perde il focus.

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

Codice:

TreeView.HideSelection = false; 
+12

in realtà su Windows7 con combinazione di colori predefinita non aiuta - quando treeview perde lo stato attivo, il nodo selezionato appare come deselezionato e non riesco a vedere la differenza da altri nodi. – oleksa

14

E 'ancora mostrato, ma solo in grigio chiaro, che a seconda del vostro schermo e la configurazione corrente può essere vicino a visibile!

Ignora l'evento OnDrawNode. Quindi tu crei e nuova classe (chiamala "SpecialTreeView") eredita da Microsoft TreeView come class SpecialTreeView : TreeView. Poi si aggiunge la seguente Override evento:

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); 
     } 
    } 
} 

compilare il codice e si dovrebbe vedere "SpecialTreeView" nella vostra cassetta degli attrezzi nella finestra di progettazione. Sostituisci TreeView con questo nuovo usando lo stesso nome e l'unica cosa che sarà diversa sono i colori di selezione. Quando selezionato sarà selectedColor, quando non selezionato il deselectedColor.

Spero che questo aiuti.

+0

Sì, lo fa, ma non lo fa :) A meno che non si selezioni HideSelection su false, che è vero per impostazione predefinita (cosa per? ... eh, tipico M $ business). Grazie per il tuo consiglio comunque, non ho notato che ha un evento "DrawNode", cercavo un tipico evento Paint ... – Istrebitel

+0

Huh .... non .... non sparare! Sto già usando il controllo TreeView personalizzato perché base uno non ha capacità drag-n-drop ... Sovraccarico di OnDragDrop, OnDragEnter ecc. Funziona ... ignorando questo non funziona. Non funziona, ho messo un punto di interruzione - niente. Cosa può essere sbagliato? – Istrebitel

+1

Ah, l'ho trovato. La sua DrawMode, se impostata su Normal, l'evento non si attiva. – Istrebitel

7

Non soluzione assolutamente perfetta, ma abbastanza vicino:

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

Grazie, questo ha aiutato. Anche se ho cambiato Brushes.Gray su SystemBrushes.Highlight – GeoffCoope

9

soluzione veloce:

Impostare le proprietà:

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

Poi nel gestore di eventi DrawNode semplicemente:

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

Su Windwos 7 questa ripristina la vecchia rendering, tra cui la casella tratteggiata intorno alla selezione (che sembra in realtà un po 'obsolete). Il testo sarà bianco con messa a fuoco e nero senza messa a fuoco. Lo sfondo rimane blu e visibile.

Questa risposta non è nuova, le altre contengono anche questi passaggi, ma questo è il minimo necessario (almeno in Windows 7, non sono stati testati altri sistemi operativi).

+0

Mi piace tranne che per due problemi: 1) L'icona della casella di controllo è tagliata sul lato destro, e 2) sembra molto più lenta quando si verifica/deseleziona .... – AndrewRalon