 |
|
 |
I submitted an alternative version. I tried to fix most of the problems I encountered.
|
|
|
|
 |
|
|
 |
|
 |
How can I invert the checkstates for this Treeview? I've already tried a couple of things, but so far haven't been very successful in my attempts...
-- modified 20 Jan '12.
|
|
|
|
 |
|
 |
I found a bug in OnNodeMouseClick.
The following line only allows a clicked node's StateImageIndex to become 1 or its earlier state. That means if it has state 2 from before, it will stay at 2:
tnBuffer.StateImageIndex = tnBuffer.Checked ? 1 : tnBuffer.StateImageIndex;
Exchange with this to fix it:
tnBuffer.StateImageIndex = tnBuffer.Checked ? 1 : 0;
-Oyvind
|
|
|
|
 |
|
 |
UPDATE!: I found the solution! See my reaction!
If I add nodes by code (some checked some not) and afterwards call the Refresh function the parent does not get updated
When I manually uncheck a checked node the parent node will update. However the problem stays with the rest of the children.
Can anyone help me? I'm using VS2010.
modified 23 Sep '11.
|
|
|
|
 |
|
 |
I FOUND THE SOLUTION!
Replace the Refresh part with:
{
Stack<TreeNode> stNodes;
TreeNode tnStacked;
base.Refresh();
if (!CheckBoxes) return;
base.CheckBoxes = false;
stNodes = new Stack<TreeNode>(this.Nodes.Count); foreach (TreeNode tnCurrent in this.Nodes) stNodes.Push(tnCurrent);
_bPreventCheckEvent = true;
while (stNodes.Count > 0)
{ tnStacked = stNodes.Pop(); if (tnStacked.StateImageIndex == -1) tnStacked.StateImageIndex = tnStacked.Checked ? 1 : 0; if (!tnStacked.Checked)
{
if (tnStacked.Nodes.Count > 0 && AllChildsChecked(tnStacked))
{
tnStacked.StateImageIndex = 1;
tnStacked.Checked = true;
}
else if (tnStacked.Nodes.Count > 0 && HasCheckedChild(tnStacked))
{
tnStacked.StateImageIndex = 2;
}
}
for (int i = 0; i < tnStacked.Nodes.Count; i++) stNodes.Push(tnStacked.Nodes[i]); }
_bPreventCheckEvent = false;
}
protected Boolean HasCheckedChild(TreeNode tn)
{
Boolean hasChecked = false;
foreach (TreeNode child in tn.Nodes)
{
if (!hasChecked)
{
if (child.Checked)
{
hasChecked = true;
}
else
{
hasChecked = HasCheckedChild(child);
}
}
}
return hasChecked;
}
protected Boolean AllChildsChecked(TreeNode tn)
{
Boolean allChildsChecked = true;
foreach (TreeNode child in tn.Nodes)
{
if (allChildsChecked)
{
if (!child.Checked)
{
allChildsChecked = false;
}
else
{
allChildsChecked = AllChildsChecked(child);
}
}
}
return allChildsChecked;
}
modified 23 Sep '11.
|
|
|
|
 |
|
 |
Hi there! Really awesome functionality but it appears that the StateImageIndex property doesn't return the correct value.
Add a AfterCheck event to the control and make it assign the StateImageIndex to the node's text, then play with checking/unchecking the nodes and you will see the the nodes are renamed improperly.
Tried it with VS2008 on Win7 and on WinXP with the same result. It seems that the StateImageIndex property returns the previous value, not the actual one.
Viaceslav Dymarski
|
|
|
|
 |
|
 |
Just add
tnBuffer.StateImageIndex = tnBuffer.Checked ? 1: 0;
when it fills the stack with the child nodes.
Like that :
do { // let's pop node from stack,
tnBuffer = stNodes.Pop(); // inherit buffered node's
tnBuffer.Checked = e.Node.Checked;// check state and push
tnBuffer.StateImageIndex = tnBuffer.Checked ? 1: 0; // Update stateimageindex
for (int i = 0; i < tnBuffer.Nodes.Count; i++) // each child on the stack
stNodes.Push(tnBuffer.Nodes[i]);// until there is no node
} while (stNodes.Count > ); // left.
|
|
|
|
 |
|
|
 |
|
 |
Great article you posted on wordpress. But: the way you described in your article won't work with this treeview, because we're self-rendering our checkboxes here and don't use the original ones. So your post to *this* article is completely senseless.
|
|
|
|
 |
|
 |
Hi there,
Excellent control - saved me loads of time writing this myself!
I do have one small issue though, which is that if the user clicks on a node but NOT on the checkbox, OnNodeMouseClick() event is fired and the _bPreventCheckEvent flag gets set to true. This means that subsequently setting the checked/unchecked state through code doesn't result in the tree updating correctly as the OnAfterCheck() code doesn't call OnNodeMouseClick(). This will persist until the next time the user DOES click a checkbox (which ultimately resets the _bPreventCheckEvent flag back to false).
I can't see any obvious reason why the code cannot be changed as follows (moving the _bPreventCheckEvent = true line to after the check for a valid click on the checkbox) but I'm not sure I've walked through every possible scenario!
base.OnNodeMouseClick(e);
iSpacing = ImageList == null ? 0 : 18; if ((e.X > e.Node.Bounds.Left - iSpacing || e.X < e.Node.Bounds.Left - (iSpacing + 16)) && e.Button != MouseButtons.None)
{ return; }
_bPreventCheckEvent = true;
Regards,
Bert
|
|
|
|
 |
|
 |
Shame on me! There is a bug in OnNodeMouseClick() ...
Try to replace...
if ((e.X > e.Node.Bounds.Left - iSpacing || e.X < e.Node.Bounds.Left - (iSpacing + 16)) && e.Button != MouseButtons.None)
{ return; }
...with...
if ((e.X > e.Node.Bounds.Left - iSpacing || e.X < e.Node.Bounds.Left - (iSpacing + 16)) && e.Button != MouseButtons.None)
{
_bPreventCheckEvent = true;
return;
}
...for a possible solution.
|
|
|
|
 |
|
 |
Hi,
That wouldn't change anything as the flag's already set to true before the if statement; I guess you meant "_bPreventCheckEvent = false;" inside that if clause, however I've tried this already and it seems there are scenarios where this causes the code to re-enter and you get an unhandled exception.
Tracing through all the possible combination of events is difficult, isn't it, especially as the Microsoft class is not consistent (hence some of the original bugs)?!
|
|
|
|
 |
|
 |
hi!
I add nodes to the treeview in my form.load event.
After adding i set the StateImageIndex to a value 0,1,2 - the values are correct in order to your description.
Lets say a structure like that:
Node1 stateimageindex 2
-Node2 stateimageindex 1
-Node3 stateimageindex 1
-Node4 stateimageindex 0
First issue:
When i deselect Node 3 or 2 Node 1 also becomes StateImageIndex 0.
When i select node 4 first and deselect node 3, Node 1 is correct.
Second issue:
When i select Node 4 first, node 1 doesnt Update to state 1 i had to click one more!
|
|
|
|
 |
|
 |
StateImgaeIndex must not be set directly. You have to set Checked state. So StateImageIndex will be calculated automatically.
|
|
|
|
 |
|
 |
Which checked value do i have to set on my parent node if one child is checked and one is unchecked?
I save the stateimageindex to remember on restart which boxes were checked.
So i set these values:
Stateimageindex = 0 is unchecked
Stateimageindex = 1 is checked
Stateimageindex = 2 is ????
i have the problem, that my parent node either checked or unchecked but not filled out
thanks!
|
|
|
|
 |
|
 |
Just set the status of the child nodes, the status of the parents depends on the status of their children
|
|
|
|
 |
|
 |
hi!
Thank you that works fine.
But now i have the problem, that some nodes have Stateimageindex = 1 and are Checked even if i had unchecked them o.O
now i tried a treeview.update() and treeview.refresh() before i read those values but some nodes are not correct.
how can that be?
|
|
|
|
 |
|
 |
Hello,
If you are using an old version of this control, try update it downloading the new version, if the problem continue, report the bug
|
|
|
|
 |
|
 |
Great code and you've saved me a lot of work - especially as this is my first time with C#. Think I've found a bug though.
If a node is unchecked, checking a child node changes the StateImageIndex to mixed. This is correct.
However, it also changes the Checked state to true, which I think is incorrect as when walking the tree in code it appears the node is checked when it is not.
Removing the following line in OnNodeMouseClick resolves this :
tnBuffer.Parent.Checked = bMixedState || (iIndex > 0); // set parent's check state and
Also, any chance you can update the download code with all the bugfixes found & fixed in comments? I believe there are two that must currently be fixed manually after obtaining the latest zip file.
|
|
|
|
 |
|
 |
Setting check state to true on setting state image index to mixed is absolutely correct. You can't select a subnode without having its parent to be checked. You may wan't to have a different logic on this tree but the current intention of this code is the one mentioned above.
The articles zip file will be updated in a few days when code project's reviewers have processed it.
modified on Monday, May 30, 2011 4:33 AM
|
|
|
|
 |
|
 |
I use the control in order to the user to select some nodes of the tree and then according to the nodes that are selected, add records to a database.
When the node is not selected, the value of StateImageIndex is 0.
When the node is mixed, the value of StateImageIndex is 2.
But when the node is selected, the value of StateImageIndex should be 1, but returns 0.
Anyone else the same thing happens? How can I fix the problem?
Sorry for my English, I used Google translator as best I could.
Regards and thanks.
|
|
|
|
 |
|
 |
You're absolutely right. A fix will be provided in updated project zip file comming in a few days.
|
|
|
|
 |
|
 |
at least for me (VS2010). Also I have found that when there is a parentnode in mixed state with checked grandchildren from different unchecked (mixed state) children, unchecking one grandchild will also erase the mixed state of the parentnode. I have changed the code as follows to resolve both issues:
added this function:
protected Boolean hasCheckedChild(TreeNode tn)
{
Boolean hasChecked = false;
foreach (TreeNode child in tn.Nodes)
{
if (!hasChecked)
{
if (child.Checked)
{
hasChecked = true;
}
else
{
hasChecked = hasCheckedChild(child);
}
}
}
return hasChecked;
}
changed
if (tnStacked.StateImageIndex == -1)
tnStacked.StateImageIndex = tnStacked.Checked ? 1 : 0;
to
tnStacked.StateImageIndex = tnStacked.Checked ? 1 : (hasCheckedChild(tnStacked) ? 2 : 0);
and in OnNodeMouseClick() commented out everything after while (stNodes.Count > 0); and replaced it by
Refresh();
This is not as efficient as the original, but works for me.
modified on Monday, March 14, 2011 7:29 AM
|
|
|
|
 |
|
 |
First, thanks for the code.
Here's the scenario
A1
--B1
--B2
----C1
----C2
------D1
------D2
This works:
* Checking A1 will correctly check B1, B2, C1, C2, D1, and D2
* Unchecking D2 will cause C2, B2, and A1 to go to StateImageIndex = 2 (Mixed)
* Collapsing at A1, A1 still shows StateImageIndex = 2 (Mixed)
What doesn't work:
* Expanding at A1 (after the collapse above) incorrectly shows B2 as StateImageIndex = 1 (Checked)
* Collapsing then expanding at B2 incorrectly shows C2 as StateImageIndex = 1 (Checked)
This gives incorrect readings when iterrating through the tree to check state. Help?
Thanks,
Danny
|
|
|
|
 |