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:
What is the problem?
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;
}
}
}
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 atonPaint
event,Hope helps,