I have the folowing use of RadTreeView. I use Telerik_2012_3_1129
I bind RadTreeView hierarchically to ObservableCollection<FilterTreeNode>
For the RadTreeView ItemContainerStyle I use following style:
Steps of usage:
1. I initialize observable collection with few levels, eg. L1, L2, L3 (Items from level L1 are expanded by default). Item1 in L2 contains few items.
2. I bind this observable collection to the tree. Everything is working correctly.
3. After a while in separate thread I finds new element that I need to add to the Item1 (from the level L2) which wasn't expanded yet, but it have few items.
4. I use Application.Current.Dispatcher.Invoke((Action) (AddRecordsFromQueue)) method to add these new elements to the tree in UI thread.
5. I create FilterTreeNode class for the new element and by default this class have _checkState = ToggleState.On
6. I add this new element to _children collection of element Item1
7. AND THAN: suddenly Item1 is unchecked automatically in the tree :(
I tried to investigate this and looked into the RadTreeViewItem code which is invoked in stack trace when its CheckState is changing to ToggleState.Off
So what is happening:
1. MeassureOverride is invoked on RadTreeViewItem related to my Item1.
2. In MeasureOverride the method this.SetCheckStateWithNoPropagation(RadTreeViewItem.CalculateItemCheckState(this));
3. In CalculateItemCheckState the following code is invoked:
5. Previous method probably returns ToggleState.Off and set in to the RadTreeViewItem
6. Via binding the CheckState in my Item1 is set to ToggleState.Off
First, the logic in the CalculateItemCheckState is interesting. Why Parent item gets CheckState set to ToggleState.Indeterminate when it contains at least 1 child in ToggleState.Indeterminate state? This is strange behaviour. I think some users (e.g. me) would like to have parent node checked no matter what are the states of its children.
Second, the most important is that before the CheckState in the Item1 was automatically set to ToggleState.Off there was no checking of the CheckState of the child items (I checked it by putting breakpoint in getter). So probably UI children of Item1 weren't created yet or they were created but wasn't binded yet to the underlying FilterTreeNode objects, so RadTreeViewItems had ToggleState.Indeterminate state before binding.
Probably children UI items wasn't created yet if parent wasn't expanded, so in that case the logic in section 3 should return the current CheckState of the item, but somehow it returns ToggleState.Off.
I also tested the case when I have Item1 expanded before this new element is added. In this case the CheckState of Item1 is automatically set to ToggleState.Indeterminate.
So, am I doing something wrong or it is a bug? What can I do to stop getting my tree nodes unchecked automatically? I think that if it is a bug not just my bad usage of this control than it is critical.
I think that this problem is also somehow related to these 2 problems:
http://www.telerik.com/community/forums/wpf/treeview/binding-to-checkstate.aspx
http://www.telerik.com/community/forums/wpf/treeview/databinding-for-checkstate.aspx
Regards,
Adrian
I bind RadTreeView hierarchically to ObservableCollection<FilterTreeNode>
public
class
FilterTreeNode : NotificationObject
{
private
ToggleState _checkState = ToggleState.On;
protected
ObservableCollection<FilterTreeNode> _children;
public
ToggleState CheckState
{
get
{
return
_checkState; }
set
{
if
(_checkState != value)
{
_checkState = value;
RaisePropertyChanged(()=>CheckState);
}
}
}
public
ObservableCollection<FilterTreeNode> Children
{
get
{
return
_children; }
set
{
if
(_children != value)
{
_children = value;
RaisePropertyChanged(() => Children);
}
}
}
}
For the RadTreeView ItemContainerStyle I use following style:
<
Style
x:Key
=
"ItemContainerStyle"
TargetType
=
"telerik:RadTreeViewItem"
>
<
Setter
Property
=
"IsExpanded"
Value
=
"{Binding IsExpanded, Mode=TwoWay}"
/>
<
Setter
Property
=
"IsSelected"
Value
=
"{Binding IsSelected, Mode=TwoWay}"
/>
<
Setter
Property
=
"CheckState"
Value
=
"{Binding CheckState, Mode=TwoWay}"
/>
<
Setter
Property
=
"MinHeight"
Value
=
"0"
></
Setter
>
</
Style
>
Steps of usage:
1. I initialize observable collection with few levels, eg. L1, L2, L3 (Items from level L1 are expanded by default). Item1 in L2 contains few items.
2. I bind this observable collection to the tree. Everything is working correctly.
3. After a while in separate thread I finds new element that I need to add to the Item1 (from the level L2) which wasn't expanded yet, but it have few items.
4. I use Application.Current.Dispatcher.Invoke((Action) (AddRecordsFromQueue)) method to add these new elements to the tree in UI thread.
5. I create FilterTreeNode class for the new element and by default this class have _checkState = ToggleState.On
6. I add this new element to _children collection of element Item1
7. AND THAN: suddenly Item1 is unchecked automatically in the tree :(
I tried to investigate this and looked into the RadTreeViewItem code which is invoked in stack trace when its CheckState is changing to ToggleState.Off
So what is happening:
1. MeassureOverride is invoked on RadTreeViewItem related to my Item1.
2. In MeasureOverride the method this.SetCheckStateWithNoPropagation(RadTreeViewItem.CalculateItemCheckState(this));
3. In CalculateItemCheckState the following code is invoked:
...
ToggleState state = ToggleState.Off;
if
(item.Items.Count > 0)
{
if
(checkedCount == item.Items.Count)
{
state = ToggleState.On;
}
else
if
(checkedCount + indetermCount > 0)
{
state = ToggleState.Indeterminate;
}
}
else
{
state = item.CheckState;
}
return
state;
5. Previous method probably returns ToggleState.Off and set in to the RadTreeViewItem
6. Via binding the CheckState in my Item1 is set to ToggleState.Off
First, the logic in the CalculateItemCheckState is interesting. Why Parent item gets CheckState set to ToggleState.Indeterminate when it contains at least 1 child in ToggleState.Indeterminate state? This is strange behaviour. I think some users (e.g. me) would like to have parent node checked no matter what are the states of its children.
Second, the most important is that before the CheckState in the Item1 was automatically set to ToggleState.Off there was no checking of the CheckState of the child items (I checked it by putting breakpoint in getter). So probably UI children of Item1 weren't created yet or they were created but wasn't binded yet to the underlying FilterTreeNode objects, so RadTreeViewItems had ToggleState.Indeterminate state before binding.
Probably children UI items wasn't created yet if parent wasn't expanded, so in that case the logic in section 3 should return the current CheckState of the item, but somehow it returns ToggleState.Off.
I also tested the case when I have Item1 expanded before this new element is added. In this case the CheckState of Item1 is automatically set to ToggleState.Indeterminate.
So, am I doing something wrong or it is a bug? What can I do to stop getting my tree nodes unchecked automatically? I think that if it is a bug not just my bad usage of this control than it is critical.
I think that this problem is also somehow related to these 2 problems:
http://www.telerik.com/community/forums/wpf/treeview/binding-to-checkstate.aspx
http://www.telerik.com/community/forums/wpf/treeview/databinding-for-checkstate.aspx
Regards,
Adrian