Why CheckedItems collection is readonly ? How can we check the items programmatically ? In fact, I try to synchronize my checked items collection of my viewmodel with the CheckedItems collection of the RadTreeView but I didn't succeed. How can I do this ?
Cordially,
Kakone.
7 Answers, 1 is accepted
You cannot bind a collection of business objects to the CheckedItems property of the RadTreeView since the tree doesnt`t know the exact location of the items he gets and doesn`t have a built-in algorithm that can search and check RadTreeViewItems (that may have not been generated yet) while iterating through business items` collection.
Instead, you can bind the IsChecked property of the RadtreeViewItem to a property from your ViewModel
via ContainerBindings.
Additionally, in order to Check tree items from the code behind, you first need to access a particular RadTreeViewItem via the GetItemByPath() method or ContainerFromItemRecursive() (only if the containers are generated).
You can examine the attached solution that demonstrates the use of the GetItemByPath().
Feel free to ask if you need further assistance.
All the best,
Petar Mladenov
the Telerik team
For the moment, I do this (but it would be nice to have a such behavior directly on the Telerik RadTreeView) :
public
class
RadTreeView : Telerik.Windows.Controls.RadTreeView
{
public
RadTreeView()
{
CheckedItems =
new
ObservableCollection<
object
>();
Checked +=
new
EventHandler<Telerik.Windows.RadRoutedEventArgs>(RadTreeView_Checked);
Unchecked +=
new
EventHandler<Telerik.Windows.RadRoutedEventArgs>(RadTreeView_Unchecked);
}
public
static
readonly
new
DependencyProperty CheckedItemsProperty = DependencyProperty.Register(
"CheckedItems"
,
typeof
(ObservableCollection<
object
>),
typeof
(Atal.Client.Common.Controls.RadTreeView),
new
PropertyMetadata(
null
));
public
new
ObservableCollection<
object
> CheckedItems
{
get
{
return
GetValue(CheckedItemsProperty)
as
ObservableCollection<
object
>; }
private
set
{ SetValue(CheckedItemsProperty, value); }
}
private
void
RadTreeView_Unchecked(
object
sender, Telerik.Windows.RadRoutedEventArgs e)
{
CheckedItems.Remove(((RadTreeViewItem)e.OriginalSource).Item);
}
private
void
RadTreeView_Checked(
object
sender, Telerik.Windows.RadRoutedEventArgs e)
{
var checkedItems = CheckedItems;
var item = ((RadTreeViewItem)e.OriginalSource).Item;
if
(!checkedItems.Contains(item))
{
checkedItems.Add(item);
}
}
protected
override
void
OnItemPrepared(RadTreeViewItemPreparedEventArgs e)
{
base
.OnItemPrepared(e);
e.PreparedItem.IsChecked = CheckedItems.Contains(e.PreparedItem.Item);
}
}
Cordially,
Kakone.
Since RadTreeView is an ItemsControl, we had decided that this is the best approach in implementing the CheckedItems and SelectedItems properties and this feature request cannot be taken into consideration. You can find more info on this topic here. ( the last post from Kiril Stanoev)
Feel free to ask if you need further assistance. We would be glad to help you.
All the best,
Petar Mladenov
the Telerik team
Thanks for your answer. You talk about SelectedItems, but with the SelectedItems collection, it works for visible items. I don't understand why there is no the same behavior with the CheckedItems collection, it is the same principle. Even it doesn't work fully (only for visible items), it should be implemented with the CheckedItems collection.
But, globally, in my mind, I think these two approaches are good and should work with the CheckedItems collection of the RadTreeView :
- a CheckedItems collection on the DataContext of the RadTreeView and a synchronization of the collections like this or,
- a IsChecked property on the DataItem ViewModel.
Personnaly, I prefer the first approach, the IsChecked or the IsSelected properties are unnecessary. In a big collection (100 000 items), why add 100 000 bytes (the IsChecked boolean property) for only one or two checked items ?
Cordially,
Kakone.
In order to be implemented such feature, it is mandatory to be fulfilled all boundary cases like the one with the invisible items.
Considering you have many other non-boolean fields in every RadTreeViewItem, you should`n worry about this boolean property.
Feel free to ask if you need more info.
Greetings,
Petar Mladenov
the Telerik team
In fact, the real problem is that I can't reuse the same datacontext between a RadGridView for example and a RadTreeView. With the RadGridView, I can use a DataContext with a SelectedItems collection but I can't reuse this same DataContext with the RadTreeView.
I think it's a pity we can't use both approaches with the RadTreeView.
Cordially,
Kakone.
I believe you can modify your data context to fit both controls. The TreeView exposes a SelectedItems collection which has private setter. So if you want to manipulate the Selecteditems collection of your view model and those changes to take effect on the visual elements you can do the following:
1. Implement IsSelected and CheckState properties in your view model to support two way binding.
2. When adding or removing items from the SelectedItems or CheckedItems collection in the view model perform a modification of respective item's property. Thus, adding new item to the SelectedItems collection in the view model will force the change of item's IsSelected property and that change will fire the binding resulting in visual change.
In some cases it would be better to have two different view models for the same data. The view model should be specific to the view (or several views if possible) and not something generic that fit every view component.
Hristo
the Telerik team