2012-04-05 5 views
23

Gretings.C# WinForms markiert den Treenode, wenn die Treeview keinen Fokus hat

Ich mache eine Schnittstelle, um Szenarien für ein Spiel zu bearbeiten. Im Grunde besteht es aus Ereignissen, die Bedingungen und Aktionen verschachtelt haben. Also plante ich zwei Baumansichten zu verwenden - eine für die Auswahl des Ereignisses und andere für die Auswahl der Bedingung/Aktion innerhalb des zu bearbeitenden Ereignisses.

Nun, wenn ich ein Ereignis (in der linken Baumansicht) auswähle und dann versuche, etwas in der rechten Baumansicht auszuwählen, wird in der linken Baumansicht das blaue Auswahlrechteck nicht mehr angezeigt. Dies ist offensichtlich schlecht, da der Benutzer jetzt nicht weiß, welches Ereignis er bearbeitet!

Die einzige Möglichkeit, eine Art von Informationen über die aktuelle Auswahl beizubehalten, ist die Verwendung von SelectedImageIndex, aber das ist nur ein kleines Bild, das anders sein wird.

Gibt es eine andere Möglichkeit, den Treenode zu markieren, während die Treeview nicht fokussiert ist? Ich weiß, ich kann nur Graphics.DrawRectangle oder so etwas, aber ich habe gehört, dass die Zeichnung in Paint-Ereignis getan werden soll und Treeview hat keine Farbe Ereignis ... Also ich denke, wenn ich es auf das Ereignis der Fokus verlieren, und ziehen Sie dann das Formular aus dem Bildschirm oder etwas, wird es "gelöscht" werden?

Wie dem auch sei mir bitte, sagen Sie, wenn Sie eine Idee (andere als ein separates Symbol mit für ausgewählte und nicht ausgewählte treenode)

Dank!

+0

Das Bild, das Sie gepostet haben, ist weg. Hast du irgendwo eine Kopie? Ich werde den Link in der Zwischenzeit entfernen .. –

Antwort

49

Was Sie suchen, ist die HideSelection Eigenschaft auf der TreeView.

Von MSDN:

Ruft einen Wert ab, der angibt, ob der ausgewählte Strukturknoten noch hervorgehoben bleibt, wenn der Baumansicht den Fokus verloren hat.

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

Code:

TreeView.HideSelection = false; 
+12

eigentlich unter Windows7 mit Standard-Farbschema das hilft nicht - wenn Treeview verliert Fokus dann ausgewählte Knoten wie deaktiviert scheint und ich kann nicht den Unterschied von einem anderen Knoten zu sehen. – oleksa

14

Es wird noch gezeigt, aber nur in hellgrau, die je auf dem Bildschirm und aktuellen Setup in der Nähe in sichtbar sein!

Überschreiben Sie das OnDrawNode-Ereignis. Sie erstellen also eine neue Klasse (nennen Sie sie "SpecialTreeView") und erben von der Microsoft TreeView wie class SpecialTreeView : TreeView. Dann fügen Sie das folgende Ereignis überschreiben:

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

Kompilieren Sie den Code, und Sie sollten „SpecialTreeView“ in Ihrem Werkzeugkasten im Designer sehen. Ersetzen Sie Ihr TreeView durch dieses neue mit dem gleichen Namen und das einzige, was anders sein wird, sind die Auswahlfarben. Wenn ausgewählt, ist es selectedColor, wenn nicht die deselectedColor ausgewählt ist.

Ich hoffe, das hilft.

+0

Ja, tut es, aber nur es tut nicht :) Es sei denn, Sie setzen HideSelection auf false, was standardmäßig gilt (was für? ... äh, typische M $ Geschäft). Vielen Dank für Ihren Rat, ich habe nicht bemerkt, dass es "DrawNode" Event, war auf der Suche nach einem typischen Paint-Event ... – Istrebitel

+0

Huh .... es .... wird nicht brennen! Ich benutze bereits das benutzerdefinierte TreeView-Steuerelement, weil Base One keine Drag-and-Drop-Funktionen hat ... Überschreiben von OnDragDrop, OnDragEnter usw. funktioniert ... überschreiben dieses nicht. Es führt nur nicht aus, ich habe einen Haltepunkt gesetzt - nichts. Was kann falsch sein? – Istrebitel

+1

Ah ja, fand es. Sein DrawMode, wenn es auf Normal eingestellt ist, wird das Ereignis nicht ausgelöst. – Istrebitel

7

Nicht absolut perfekte Lösung, aber ganz in der Nähe von:

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

Danke, das hat geholfen. Obwohl ich Brushes.Gray zu SystemBrushes.Highlight – GeoffCoope

9

Schnelle Lösung:

Legen Sie die Eigenschaften:

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

Dann in den DrawNode Event-Handler einfach tun:

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

auf Windwos 7 diese bleiben das alte Rendering, einschließlich der in unterbrochenen Linien um die Auswahl (die eigentlich ein bisschen veraltet aussieht). Der Text wird weiß mit Fokus und Schwarz ohne Fokus. Der Hintergrund bleibt blau und sichtbar.

Diese Antwort ist nicht neu, die anderen enthalten auch diese Schritte, aber das ist minimal erforderlich (zumindest in Windows 7, hat nicht andere Betriebssysteme getestet).

+0

ändere Ich mag außer zwei Probleme: 1) Das Kontrollkästchen-Symbol ist auf der rechten Seite abgeschnitten, und 2) es scheint deutlich langsamer beim Ein-/Auschecken .... – AndrewRalon

Verwandte Themen