自定义 TreeView 类显示不需要的字符 [英] Custom TreeView class displays unwanted characters

查看:26
本文介绍了自定义 TreeView 类显示不需要的字符的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have created a custom TreeView class. I have a display problem when opening and closing the top nodes in that characters appears in the first column. First the tree is displayed:


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


Then after opening and closing the top nodes, unwanted characters appear in the first column:

有什么问题?

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

推荐答案

你绘制文本的次数过多,你还应该检查子节点的父节点是否展开,否则不需要DrawString 在你的循环中执行.在 onPaint 事件中像这样更改代码,

You are drawing the texts too many times, you should also check if the child node's parent is expanded, otherwise you don't need to DrawString in your loop to execute. Change you code like this at 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));
}

希望有所帮助,

这篇关于自定义 TreeView 类显示不需要的字符的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆