Reputation: 445
I have a TreeView with checkboxes like
I have added some code to show what is selected:
/// <summary>
/// Highlight checked nodes
/// </summary>
private void HighlightCheckedNodes()
{
foreach (TreeNode topNode in treeView1.Nodes)
{
if (topNode.Checked)
{
topNode.BackColor = Color.Yellow;
}
else
{
topNode.BackColor = Color.White;
}
foreach (TreeNode myNode in topNode.Nodes)
{
// Check whether the tree node is checked.
if (myNode.Checked)
{
// Set the node's backColor.
myNode.BackColor = Color.Yellow;
}
else
{
myNode.BackColor = Color.White;
}
}
}
}
This function is called from treeView1_AfterSelect and treeView1_AfterCheck. If I click a few times I get some nodes that are marked as checked but not yellow (the data says it's not checked) or vice versa.
So how do I make sure the data and display are in sync?
Upvotes: 0
Views: 62
Reputation: 39152
Long story short, the TreeView is buggy!
Here's an implementation that uses NativeWindow instead of deriving from TreeView. This will allow you to use the existing TreeView on your Form:
public partial class Form1 : Form
{
private TreeViewSuppressDoubleClick treeViewHelper;
private void Form1_Load(object sender, EventArgs e)
{
treeViewHelper = new TreeViewSuppressDoubleClick(this.treeView1);
}
public class TreeViewSuppressDoubleClick : NativeWindow
{
public TreeViewSuppressDoubleClick(TreeView treeView)
{
if (treeView != null && treeView.IsHandleCreated)
{
this.AssignHandle(treeView.Handle);
}
}
protected override void WndProc(ref Message m)
{
if (m.Msg != 0x203)
base.WndProc(ref m);
}
}
private void treeView1_AfterCheck(object sender, TreeViewEventArgs e)
{
e.Node.BackColor = e.Node.Checked ? Color.Yellow : Color.White;
}
}
After this you'll notice that the TreeView isn't as responsive to clicks, but it does stay in sync now.
Note the simplified method for changing the BackColor on a check/uncheck.
Also, here's an alternate HighlightCheckedNodes() using recursion to get all the nodes:
private void HighlightCheckedNodes(TreeNode node)
{
if (node == null)
{
foreach (TreeNode topNode in treeView1.Nodes)
{
HighlightCheckedNodes(topNode);
}
}
else
{
node.BackColor = node.Checked ? Color.Yellow : Color.White;
foreach (TreeNode curNode in node.Nodes)
{
HighlightCheckedNodes(curNode);
}
}
}
You'd call it using HighlightCheckedNodes(null);
.
Upvotes: 1