I have a custom TreeView class. I don't like how the text and the background color line up. The text appears to high (or background too low):
I don't see any way of positioning the text, so I've tried moving the Y position of the background up 2 pixels. This causes lines to appear when
clicking from one node to another:
I think the previous node background is not being redrawn, though I think I have the code for that, in CustomTreeView.OnPaint()
, in the else // not selected
section
Is there anything I can do about this or is this just the way it has to be?
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 BackGroundBrushWindows = new System.Drawing.SolidBrush(System.Drawing.SystemColors.Window))
using (System.Drawing.SolidBrush ForeGroundBrushWindows = new System.Drawing.SolidBrush(System.Drawing.SystemColors.WindowText))
using (System.Drawing.SolidBrush BackGroundBrushHighLight = new System.Drawing.SolidBrush(System.Drawing.Color.CornflowerBlue))
//using (System.Drawing.SolidBrush ForeGroundBrushHighLight = new System.Drawing.SolidBrush(System.Drawing.SystemColors.WindowText))
{
e.Graphics.FillRectangle(BackGroundBrushWindows, 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 = ForeGroundBrushWindows; // 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("OnPaint: Nodes[index].GetNodeCount: " + nodeCount);
foreach (TreeNode childNode in topLevelTreeNode.Nodes)
{
System.Diagnostics.Trace.WriteLine(" childNode: " + childNode.Tag + " IsSelected: " + childNode.IsSelected);
if (childNode.IsSelected)
{
//CurrentNode = ForeGroundBrushWindows;
Rectangle bounds = childNode.Bounds;
//bounds.Y += -2; // move up 2
e.Graphics.FillRectangle(BackGroundBrushHighLight, bounds);
}
else // not selected
{
//CurrentNode = ForeGroundBrushWindows;
Rectangle bounds = childNode.Bounds;
//bounds.Y += -2; // move up 2
e.Graphics.FillRectangle(BackGroundBrushWindows, bounds);
}
if (childNode.Parent.IsExpanded)
{
Rectangle bounds = childNode.Bounds;
//bounds.Y += -2; // move up 2
e.Graphics.DrawString(childNode.Text, this.Font, CurrentNode, Rectangle.Inflate(bounds, 2, 0));
}
}
}
}
}
}
public partial class TreeViewDialog : Form
{
// 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 = treeNodeJazz.Nodes.Add(ProjectConstants.JAZZ_GILLESPIE, ProjectConstants.JAZZ_GILLESPIE);
treeNode.Tag = ProjectConstants.JAZZ_GILLESPIE;
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_BJORK, ProjectConstants.ROCK_BJORK);
treeNode.Tag = ProjectConstants.ROCK_BJORK;
treeNode = treeNodeRock.Nodes.Add(ProjectConstants.ROCK_SPRINGSTEEN, ProjectConstants.ROCK_SPRINGSTEEN);
treeNode.Tag = ProjectConstants.ROCK_SPRINGSTEEN;
treeNode = treeNodeRock.Nodes.Add(ProjectConstants.ROCK_LADY_GAGA, ProjectConstants.ROCK_LADY_GAGA);
treeNode.Tag = ProjectConstants.ROCK_LADY_GAGA;
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;
}
}
}
See Question&Answers more detail:
os