web-dev-qa-db-ja.com

TreeViewがフォーカスされていないときにTreeNodeがBackColorを選択した

選択したTreeNodeにSystemColors.Highlight BackColorを保持させ、TreeViewにフォーカスがない簡単な方法はありますか? HideSelectionがfalseに設定されていても、選択されたBackColorはほとんど見えないためです。

TreeViewがフォーカスされている間に選択されたTreeNode:

Focused

TreeViewがフォーカスを持たない間に選択されたTreeNode:

Unfocused

前もって感謝します。

編集: DrawModeをOwnerDrawAllに設定し、カスタムDrawNodeイベントを追加できることを認識しています。以前にこれを試みましたが、私が抱えている問題は、TreeNodeの対応するImageKeyを適切に描画する方法がわからないことです。

22
Spark

ソリューションは魅力のように機能します:

public TreeNode previousSelectedNode = null;
private void treeView1_Validating(object sender, System.ComponentModel.CancelEventArgs e)
{
    treeView1.SelectedNode.BackColor = SystemColors.Highlight;
    treeView1.SelectedNode.ForeColor = Color.White;
    previousSelectedNode = treeView1.SelectedNode;
}

private void treeView1_AfterSelect(object sender, TreeViewEventArgs e)
{
    if(previousSelectedNode != null)
    {
        previousSelectedNode.BackColor = treeView1.BackColor;
        previousSelectedNode.ForeColor = treeView1.ForeColor;
    }
}
13
Spark

SystemColors.Highlight背景色を保持するだけでよい場合、TreeViewDrawModeプロパティをTreeViewDrawMode.OwnerDrawAllに設定する必要はありません。 TreeViewDrawMode.OwnerDrawTextに設定するだけで十分です。したがって、TreeNodeに対応するImageKeyを描画することを心配する必要はありません。

  1. TreeView.DrawModeTreeViewDrawMode.OwnerDrawTextに設定します。

    treeView.DrawMode = TreeViewDrawMode.OwnerDrawText;
    
  2. Treview.HideSelectionfalseに設定して、ノードの状態が選択されたままになるようにします。

    treeView.HideSelection= false;
    
  3. DrawNodeイベントハンドラーを追加して、SystemColors.Highlight色を使用して背景を描画します。

    private void treeView_DrawNode(object sender, DrawTreeNodeEventArgs e)
    {
      if (e.Node == null) return;
    
      // if treeview's HideSelection property is "True", 
      // this will always returns "False" on unfocused treeview
      var selected = (e.State & TreeNodeStates.Selected) == TreeNodeStates.Selected;
      var unfocused = !e.Node.TreeView.Focused;
    
      // we need to do owner drawing only on a selected node
      // and when the treeview is unfocused, else let the OS do it for us
      if (selected && unfocused)
      {
        var font = e.Node.NodeFont ?? e.Node.TreeView.Font;
        e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds);
        TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, SystemColors.HighlightText, TextFormatFlags.GlyphOverhangPadding);
      }
      else
      {
        e.DrawDefault = true;
      }
    }
    
12
IronGeek

私はこのソリューションを使用しましたが、うまく機能しています

private void treeView1_Enter(object sender, EventArgs e)
{
   if (treeView1.SelectedNode != null)
   {
       treeView1.SelectedNode.BackColor = Color.Empty;
       treeView1.SelectedNode.ForeColor = Color.Empty;
   }
}

private void treeView1_Leave(object sender, EventArgs e)
{
   if (treeView1.SelectedNode != null)
   {
       treeView1.SelectedNode.BackColor = SystemColors.Highlight;
       treeView1.SelectedNode.ForeColor = Color.White;
   }
}

[〜#〜] edit [〜#〜]

this ドキュメントに基づいて、

デフォルトはColor.Emptyです

したがって、treeView1_Enterこのように色を設定する方が良い

treeView1.SelectedNode.BackColor = Color.Empty;
treeView1.SelectedNode.ForeColor = Color.Empty;

前の回答

treeView1.SelectedNode.BackColor = treeView1.BackColor;
treeView1.SelectedNode.ForeColor = treeView1.ForeColor;
4
Afrig Aminuddin

ツリービューがフォーカスを失ったときに選択したノードを強調表示する必要がある場合は、treeView.HideSelection = false;を使用します。

実際には、デフォルトでは選択されたノードは強調表示されますが表示されないため、HideSelectionプロパティをfalseにするだけです。

3
Vikash Kumar

この素晴らしいソリューションを見つけました ここ(MSDN)

私にとって素晴らしい仕事でした。他の人の助けになることを願っています。

  1. プロジェクトに新しいクラス(MyTreeView.csというファイル)を追加し、以下に示すコードを貼り付けます。
  2. コンパイル
  3. 「MyTreeView」という新しいコントロールをツールボックスの上部からフォームにドロップします。

あなたが何をしているのか知っていれば、あなたもそれをカスタマイズすることができます

using System;
using System.Drawing;
using System.Windows.Forms;



class MyTreeView : TreeView {
    public MyTreeView() {
        this.DrawMode = TreeViewDrawMode.OwnerDrawText;
    }
    protected override void OnDrawNode(DrawTreeNodeEventArgs e) {
        TreeNodeStates state = e.State;
        Font font = e.Node.NodeFont ?? e.Node.TreeView.Font;
        Color fore = e.Node.ForeColor;
        if (fore == Color.Empty) fore = e.Node.TreeView.ForeColor;
        if (e.Node == e.Node.TreeView.SelectedNode) {
            fore = SystemColors.HighlightText;
            e.Graphics.FillRectangle(SystemBrushes.Highlight, e.Bounds);
            ControlPaint.DrawFocusRectangle(e.Graphics, e.Bounds, fore, SystemColors.Highlight);
            TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, fore, TextFormatFlags.GlyphOverhangPadding);
        }
        else {
            e.Graphics.FillRectangle(SystemBrushes.Window, e.Bounds);
            TextRenderer.DrawText(e.Graphics, e.Node.Text, font, e.Bounds, fore, TextFormatFlags.GlyphOverhangPadding);
        }
    }
}
1
ukie

IronGeeksの回答のこのバリアントは、私にとってはうまく機能し、 太字ノード で機能します。

_Private Sub TreeView1_DrawNode(sender As Object, e As DrawTreeNodeEventArgs) Handles trvIdent.DrawNode
    Dim treeView = e.Node.TreeView
    Dim selected = (e.Node Is treeView.SelectedNode)
    Dim unfocused = Not treeView.Focused
    Dim font = If(e.Node.NodeFont IsNot Nothing, e.Node.NodeFont, treeView.Font)
    Dim textSize = e.Graphics.MeasureString(e.Node.Text, font)
    Dim bounds = New Rectangle(e.Bounds.X, e.Bounds.Y,
                               Convert.ToInt32(textSize.Width),
                               Math.Max(Convert.ToInt32(textSize.Height), e.Bounds.Height))

    e.DrawDefault = False

    If selected Then
        e.Graphics.FillRectangle(SystemBrushes.Highlight, bounds)
        e.Graphics.DrawString(e.Node.Text, font, SystemBrushes.HighlightText, bounds.Location)
    Else
        e.Graphics.FillRectangle(SystemBrushes.Window, bounds)
        e.Graphics.DrawString(e.Node.Text, font, SystemBrushes.WindowText, bounds.Location)
    End If
    'e.Graphics.DrawRectangle(Pens.Magenta, bounds)
End Sub
_

主な違いは、TreeViewにフォーカスがある場合でもカスタム描画が行われることです。そして、DrawString()の代わりにDrawText()が使用されます。

0
dummy

これは、ツリービューのデフォルトの動作です。変更するには、drawnodeをオーバーライドするだけです。ここで説明できるよりも優れた別のスタックオーバーフローの答えがあります。

TreeViewDrawMode.OwnerDrawAllを使用してTreeViewで選択したノードの背景色を変更する方法

0
Allen

次のコードは、プログラムで選択されたノードでも機能します。

public TreeNode m_previousSelectedNode = null;
private void m_treeView_AfterSelect(object sender, TreeViewEventArgs e)
{
    if (m_previousSelectedNode != null)
    {
        m_previousSelectedNode.BackColor = m_treeView.BackColor;
        m_previousSelectedNode.ForeColor = m_treeView.ForeColor;
    }

    e.Node.BackColor = SystemColors.Highlight;
    e.Node.ForeColor = Color.White;

    m_previousSelectedNode = m_treeView.SelectedNode;
}
0
Elephant