自定义TreeView类显示不需要的字符

时间:2017-05-19 14:49:12

标签: c# winforms treeview

我创建了一个自定义TreeView类。打开和关闭顶部节点时出现显示问题,第一列中出现该字符。 首先显示树:

enter image description here
然后在打开和关闭顶部节点后,第一列中出现不需要的字符:

enter image description here

有什么问题?

public class CustomTreeView : TreeView
{
    public CustomTreeView() : base()
    {
        this.SetStyle(
            ControlStyles.UserPaint |
            ControlStyles.DoubleBuffer |
            ControlStyles.Opaque, true);
    }

    protected override void OnPaint(PaintEventArgs e)
    {
        using (System.Drawing.SolidBrush BackGroundBrush = new System.Drawing.SolidBrush(System.Drawing.SystemColors.Window))
        using (System.Drawing.SolidBrush ForeGroundBrush = new System.Drawing.SolidBrush(System.Drawing.SystemColors.WindowText))
        using (System.Drawing.SolidBrush BackGroundBrushHighLight = new System.Drawing.SolidBrush(System.Drawing.Color.DarkGreen))
        using (System.Drawing.SolidBrush ForeGroundBrushHighLight = new System.Drawing.SolidBrush(System.Drawing.Color.Pink))
        {
            e.Graphics.FillRectangle(BackGroundBrush, e.ClipRectangle);
            System.Drawing.SolidBrush CurrentNode;

            int count = this.Nodes.Count;
            System.Diagnostics.Trace.WriteLine("CustomTreeView.OnPaint: count: " + count);
            for (int topLevelIndex = 0; topLevelIndex < count; ++topLevelIndex)
            {
                TreeNode topLevelTreeNode = Nodes[topLevelIndex];
                CurrentNode = ForeGroundBrush; // top level always this, never selected
                e.Graphics.DrawString(topLevelTreeNode.Text, this.Font, CurrentNode, Rectangle.Inflate(topLevelTreeNode.Bounds, 2, 0));

                int nodeCount = topLevelTreeNode.GetNodeCount(true);
                System.Diagnostics.Trace.WriteLine("CustomTreeView.OnPaint: Nodes[index].GetNodeCount: " + nodeCount);

                foreach (TreeNode childNode in topLevelTreeNode.Nodes)
                {
                    if (childNode.IsSelected)
                    {
                        CurrentNode = ForeGroundBrushHighLight;
                        e.Graphics.FillRectangle(BackGroundBrushHighLight, childNode.Bounds);
                    }
                    else
                    {
                        CurrentNode = ForeGroundBrush;
                    }
                    e.Graphics.DrawString(childNode.Text, this.Font, CurrentNode, Rectangle.Inflate(childNode.Bounds, 2, 0));
                }
            }

        }
    }
}

class ProjectConstants
{
    public const string TOP_NODE_CLASSICAL = "Classical";
    public const string TOP_NODE_JAZZ = "Jazz";
    public const string TOP_NODE_ROCK = "Rock";

    public const string CLASSICAL_BEETHOVEN = "Beethoven";
    public const string CLASSICAL_MOZART = "Mozart";
    public const string CLASSICAL_CHOPIN = "Chopin";

    public const string JAZZ_MONK = "Thelonius Monk";
    public const string JAZZ_MINGUS = "Charles Mingus";
    public const string JAZZ_COLTRANE = "John Coltrane";

    public const string ROCK_CORNELL = "Chris Cornell";
    public const string ROCK_PLANT = "Robert Plant";
    public const string ROCK_SPRINGSTEEN = "Bruce Springsteen";
}

partial class TreeViewDialog
{
    /// <summary>
    /// Required designer variable.
    /// </summary>
    private System.ComponentModel.IContainer components = null;

    /// <summary>
    /// Clean up any resources being used.
    /// </summary>
    /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
    protected override void Dispose(bool disposing)
    {
        if (disposing && (components != null))
        {
            components.Dispose();
        }
        base.Dispose(disposing);
    }

    #region Windows Form Designer generated code

    /// <summary>
    /// Required method for Designer support - do not modify
    /// the contents of this method with the code editor.
    /// </summary>
    private void InitializeComponent()
    {
        this.components = new System.ComponentModel.Container();
        System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(TreeViewDialog));
        this.btnSave = new System.Windows.Forms.Button();
        this.btnCancel = new System.Windows.Forms.Button();
        this.bMusicDocumentType = new System.Windows.Forms.BindingSource(this.components);
        this.treeView = new Views.Project.CustomTreeView();
        ((System.ComponentModel.ISupportInitialize)(this.bMusicDocumentType)).BeginInit();
        this.SuspendLayout();
        // 
        // btnSave
        // 
        this.btnSave.Location = new System.Drawing.Point(227, 345);
        this.btnSave.Name = "btnSave";
        this.btnSave.Size = new System.Drawing.Size(75, 23);
        this.btnSave.TabIndex = 6;
        this.btnSave.Text = "Save    ";
        this.btnSave.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
        this.btnSave.UseVisualStyleBackColor = true;
        this.btnSave.Click += new System.EventHandler(this.btnSave_Click);
        // 
        // btnCancel
        // 
        this.btnCancel.Location = new System.Drawing.Point(12, 345);
        this.btnCancel.Name = "btnCancel";
        this.btnCancel.Size = new System.Drawing.Size(75, 23);
        this.btnCancel.TabIndex = 7;
        this.btnCancel.Text = "Cancel  ";
        this.btnCancel.TextAlign = System.Drawing.ContentAlignment.MiddleRight;
        this.btnCancel.UseVisualStyleBackColor = true;
        this.btnCancel.Click += new System.EventHandler(this.btnCancel_Click);
        // 
        // bMusicDocumentType
        // 
        this.bMusicDocumentType.DataSource = ((object)(resources.GetObject("bMusicDocumentType.DataSource")));
        this.bMusicDocumentType.Position = 0;
        // 
        // treeView
        // 
        this.treeView.HideSelection = false;
        this.treeView.Location = new System.Drawing.Point(15, 12);
        this.treeView.Name = "treeView";
        this.treeView.Size = new System.Drawing.Size(287, 303);
        this.treeView.TabIndex = 14;
        this.treeView.BeforeSelect += new System.Windows.Forms.TreeViewCancelEventHandler(this.treeViewCategoryType_BeforeSelect);
        this.treeView.NodeMouseClick += new System.Windows.Forms.TreeNodeMouseClickEventHandler(this.treeViewCategoryType_TreeNodeMouseClickEventHandler);
        // 
        // TreeViewDialog
        // 
        this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
        this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
        this.ClientSize = new System.Drawing.Size(330, 392);
        this.Controls.Add(this.treeView);
        this.Controls.Add(this.btnCancel);
        this.Controls.Add(this.btnSave);
        this.Name = "TreeViewDialog";
        this.Text = "New Music";
        ((System.ComponentModel.ISupportInitialize)(this.bMusicDocumentType)).EndInit();
        this.ResumeLayout(false);

    }

    #endregion
    private System.Windows.Forms.Button btnSave;
    private System.Windows.Forms.Button btnCancel;
    private System.Windows.Forms.BindingSource bMusicDocumentType;
    private Views.Project.CustomTreeView treeView;
}

public partial class TreeViewDialog : Form
{
    // Create a Font object for the node tags.
    private Font tagFont = new Font("Helvetica", 8, FontStyle.Bold);

    public static List<String> musicList = new List<String>(new string[] {
        //ProjectConstants.TOP_NODE_CLASSICAL,
        ProjectConstants.CLASSICAL_BEETHOVEN,
        ProjectConstants.CLASSICAL_MOZART,
        ProjectConstants.CLASSICAL_CHOPIN,
        //ProjectConstants.TOP_NODE_JAZZ,
        ProjectConstants.JAZZ_MONK,
        ProjectConstants.JAZZ_MINGUS,
        ProjectConstants.JAZZ_COLTRANE,
        //ProjectConstants.TOP_NODE_ROCK,
        ProjectConstants.ROCK_CORNELL,
        ProjectConstants.ROCK_PLANT,
        ProjectConstants.ROCK_SPRINGSTEEN,
        });

    //  Add unselectable nodes to this collection when you create them
    private List<TreeNode> _unselectableNodes = new List<TreeNode>();

    public TreeViewDialog (String documentType)
    {

        InitializeComponent();

        this.treeView.Update();

        // Add (key, text), where key is name of the tree node and text is the text to display
        TreeNode treeNodeClassical = this.treeView.Nodes.Add(ProjectConstants.TOP_NODE_CLASSICAL, ProjectConstants.TOP_NODE_CLASSICAL);
        treeNodeClassical.Tag = ProjectConstants.TOP_NODE_CLASSICAL;
        _unselectableNodes.Add(treeNodeClassical);

        TreeNode treeNode = treeNodeClassical.Nodes.Add(ProjectConstants.CLASSICAL_BEETHOVEN, ProjectConstants.CLASSICAL_BEETHOVEN);
        treeNode.Tag = ProjectConstants.CLASSICAL_BEETHOVEN;
        treeNode = treeNodeClassical.Nodes.Add(ProjectConstants.CLASSICAL_MOZART, ProjectConstants.CLASSICAL_MOZART);
        treeNode.Tag = ProjectConstants.CLASSICAL_MOZART;
        treeNode = treeNodeClassical.Nodes.Add(ProjectConstants.CLASSICAL_CHOPIN, ProjectConstants.CLASSICAL_CHOPIN);
        treeNode.Tag = ProjectConstants.CLASSICAL_CHOPIN;

        TreeNode treeNodeJazz = this.treeView.Nodes.Add(ProjectConstants.TOP_NODE_JAZZ, ProjectConstants.TOP_NODE_JAZZ);
        treeNodeJazz.Tag = ProjectConstants.TOP_NODE_JAZZ;
        _unselectableNodes.Add(treeNodeJazz);

        treeNode = treeNodeJazz.Nodes.Add(ProjectConstants.JAZZ_MONK, ProjectConstants.JAZZ_MONK);
        treeNode.Tag = ProjectConstants.JAZZ_MONK;
        treeNode = treeNodeJazz.Nodes.Add(ProjectConstants.JAZZ_MINGUS, ProjectConstants.JAZZ_MINGUS);
        treeNode.Tag = ProjectConstants.JAZZ_MINGUS;
        treeNode = treeNodeJazz.Nodes.Add(ProjectConstants.JAZZ_COLTRANE, ProjectConstants.JAZZ_COLTRANE);
        treeNode.Tag = ProjectConstants.JAZZ_COLTRANE;

        TreeNode treeNodeRock = this.treeView.Nodes.Add(ProjectConstants.TOP_NODE_ROCK, ProjectConstants.TOP_NODE_ROCK);
        treeNodeRock.Tag = ProjectConstants.TOP_NODE_ROCK;
        _unselectableNodes.Add(treeNodeRock);

        treeNode = treeNodeRock.Nodes.Add(ProjectConstants.ROCK_CORNELL, ProjectConstants.ROCK_CORNELL);
        treeNode.Tag = ProjectConstants.ROCK_CORNELL;
        treeNode = treeNodeRock.Nodes.Add(ProjectConstants.ROCK_PLANT, ProjectConstants.ROCK_PLANT);
        treeNode.Tag = ProjectConstants.ROCK_PLANT;
        treeNode = treeNodeRock.Nodes.Add(ProjectConstants.ROCK_SPRINGSTEEN, ProjectConstants.ROCK_SPRINGSTEEN);
        treeNode.Tag = ProjectConstants.ROCK_SPRINGSTEEN;

        this.treeView.ExpandAll();

        // if something was selected on the tab page, then select it here
        if (!String.IsNullOrEmpty(documentType))
        {
            TreeNode namedNode = null;
            foreach (TreeNode node in treeView.Nodes)
            {
                namedNode = getTreeNodeFromName(documentType, node);
                if (namedNode != null)
                {
                    break; // nothing found
                }
            }

            if (namedNode != null)
            {
                treeView.SelectedNode = namedNode; 
            }
            treeView.Focus();

        }

        this.treeView.EndUpdate();
    }

    public TreeNode getTreeNodeFromName(string name, TreeNode rootNode)
    {
        foreach (TreeNode node in rootNode.Nodes)
        {
            if (node.Name.Equals(name))
            {
                return node;
            }
            TreeNode next = getTreeNodeFromName(name, node);
            if (next != null)
            {
                return next;
            }
        }
        return null;
    }

    private void btnSave_Click(object sender, EventArgs e)
    {
        // nothing right now
    }


    private void btnCancel_Click(object sender, EventArgs e)
    {
        this.Close();
    }

    private void treeViewCategoryType_TreeNodeMouseClickEventHandler(object sender, TreeNodeMouseClickEventArgs eventArgs)
    {            TreeView treeView = (TreeView)sender;

        TreeNode treeNode = eventArgs.Node; // parent or child

        String nodeText = treeNode.Text;

        // if parent treeNode
        if (nodeText.Equals(ProjectConstants.TOP_NODE_CLASSICAL) ||
            nodeText.Equals(ProjectConstants.TOP_NODE_JAZZ) ||
            nodeText.Equals(ProjectConstants.TOP_NODE_ROCK))
        {
            // don't select the treeNode
        }
        else
        {  // child
        }

    }

    private void treeViewCategoryType_BeforeSelect(object sender, TreeViewCancelEventArgs eventArgs)
    {
        if (_unselectableNodes.Contains(eventArgs.Node))
        {
            eventArgs.Cancel = true;
        }
    }
}

1 个答案:

答案 0 :(得分:2)

您正在绘制文本的次数太多,您还应该检查子节点的父级是否已展开,否则您不需要在循环中DrawString执行。在onPaint event,

更改您的代码
if(childNode.IsSelected)
{
     CurrentNode = ForeGroundBrushHighLight;
     e.Graphics.FillRectangle(BackGroundBrushHighLight, childNode.Bounds);
}
else
{
     CurrentNode = ForeGroundBrush;
}
if(childNode.Parent.IsExpanded)
{
     e.Graphics.DrawString(childNode.Text, this.Font, CurrentNode, Rectangle.Inflate(childNode.Bounds, 2, 0));
}

希望有所帮助,