Hi,
I'm using MVVM (no code-behind!) with the treeview and it's on Load on demand (call method on WCF side etc...)
I would like to add search capability in TreeView, but no one of the child nodes doesn't know about his child nodes, so I need again async call WCF-method to find A WAY to proper item. It works.
But, when user clicks on item expander, occurs event "LoadOnDemand" and it passed to ViewModel:
But I have problem:
How can I expand that Item programmatically? When i set "IsExpanded = true" nothing happens, there is just spinning arrow in me tree. And event doesnt occur.
Note: when I set "IsExpanded = true" in CODE-BEHIND - everything works fine! Can I expand lod-item in ViewModel?
Thank you and sorry for my english. I would appreciate a fast response.
I'm using MVVM (no code-behind!) with the treeview and it's on Load on demand (call method on WCF side etc...)
I would like to add search capability in TreeView, but no one of the child nodes doesn't know about his child nodes, so I need again async call WCF-method to find A WAY to proper item. It works.
But, when user clicks on item expander, occurs event "LoadOnDemand" and it passed to ViewModel:
<
i:EventTrigger
EventName
=
"LoadOnDemand"
>
<
MVVMLightCommand:EventToCommand
Command
=
"{Binding LoadOnDemandCommand}"
PassEventArgsToCommand
=
"True"
/>
</
i:EventTrigger
>
But I have problem:
How can I expand that Item programmatically? When i set "IsExpanded = true" nothing happens, there is just spinning arrow in me tree. And event doesnt occur.
Note: when I set "IsExpanded = true" in CODE-BEHIND - everything works fine! Can I expand lod-item in ViewModel?
Thank you and sorry for my english. I would appreciate a fast response.
7 Answers, 1 is accepted
0
Hi Doxxer,
I am not sure if I understand your scenario completely. I am not sure where you set the IsExpanded property in your view model?
Basically if an item is expanded before its children collection is loaded, then the changed expanded state will trigger the load on demand logic - the command action in your case. However, if the item's children collection is already loaded, then changing the expanded state of the node won't trigger the LoadOnDemand logic.
However, you say that it's not only that the load on demand logic isn't triggered, but the item isn't expanded at all. This is why I wanted to ask you to please make sure that the RadTreeViewItem IsExpanded property is bound in a TwoWay mode to your business property in the view model.
If the IsExpaned property is bound in a TwoWay mode and changing the data property still doesn't affect the RadTreeViewItem, it would be best to send us a sample solution reproducing the issue so that we can examine your implementation and look for the cause of the issue.
All the best,
Tina Stancheva
the Telerik team
I am not sure if I understand your scenario completely. I am not sure where you set the IsExpanded property in your view model?
Basically if an item is expanded before its children collection is loaded, then the changed expanded state will trigger the load on demand logic - the command action in your case. However, if the item's children collection is already loaded, then changing the expanded state of the node won't trigger the LoadOnDemand logic.
However, you say that it's not only that the load on demand logic isn't triggered, but the item isn't expanded at all. This is why I wanted to ask you to please make sure that the RadTreeViewItem IsExpanded property is bound in a TwoWay mode to your business property in the view model.
If the IsExpaned property is bound in a TwoWay mode and changing the data property still doesn't affect the RadTreeViewItem, it would be best to send us a sample solution reproducing the issue so that we can examine your implementation and look for the cause of the issue.
All the best,
Tina Stancheva
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
Doxxer
Top achievements
Rank 1
answered on 17 Nov 2011, 03:14 PM
Hi, Tina
Ok, I'll try to describe the problem and my sample solution.
First of all, important notes:
Ok. Lets describe my problem:
Thank you and again and I so sorry for my English =)
P.S. I can not attach my solution...
Ok, I'll try to describe the problem and my sample solution.
First of all, important notes:
- Realy project is much more difficult, classes have much more properties, but they don't need to present my problem.
- In main project some of nodes have more than 3000 children, so I set IsVirtualized=true
- In my main project, the nesting level is unknown, so I have to use recursive calls
- Last note: In main project I create inherited class RadTreeViewEx (from RadTreeView), with 2 Dependency Properties (its for search ability), and I tried to call this.ExpandItemByPass(path), but event still doesn't occur.
Ok. Lets describe my problem:
- On server side is WCF-service. It consists of two projects, the first is simple ClassLibrary, the second is service. ClassLibrary consists of one base class, and 4 inherited classes: Depart, Group, SGroup (subgroup) and Product.
So, as you can see in the GetProductNomenclature() method, each depart contains of 5 groups, each group contains 5 subgroups. The subgroup will be loaded on demand.
And in the method GetProductsFromSGroup(), each subgroup will contain 10 items - that method will be called when event LoadOnDemand occurs.
An example of server-side code:
namespace
RCP.Server.Data
{
[DataContract]
[KnownType(
"GetKnownTypes"
)]
public
class
NomenclaturalUnit
{
public
NomenclaturalUnit()
{
Children =
new
List<NomenclaturalUnit>();
}
private
static
Type[] GetKnownTypes()
{
return
new
[] {
typeof
(Depart),
typeof
(GGroup),
typeof
(SGroup),
typeof
(Product)};
}
[DataMember]
public
decimal
ID {
get
;
set
; }
[DataMember]
public
string
Name {
get
;
set
; }
[DataMember]
public
List<NomenclaturalUnit> Children {
get
;
set
; }
}
[DataContract]
public
class
Depart : NomenclaturalUnit
{
}
[DataContract]
public
class
GGroup : NomenclaturalUnit
{
}
[DataContract]
public
class
SGroup : NomenclaturalUnit
{
}
[DataContract]
public
class
Product : NomenclaturalUnit
{
}
}
And for WCF Service:
[ServiceContract]
public
interface
IRCPMainService
{
[OperationContract]
List<NomenclaturalUnit> GetProductNomenclature();
[OperationContract]
List<NomenclaturalUnit> GetProductsFromSGroup(
int
idSgroup);
}
public
class
RCPMainService : IRCPMainService
{
public
List<NomenclaturalUnit> GetProductNomenclature()
{
var departs = Enumerable.Range(0, 5).Select(i =>
new
Depart {ID = i, Name =
string
.Format(
"Depart {0}"
, i)}).ToList();
foreach
(var depart
in
departs)
{
var groups = Enumerable.Range(0, 5).Select(i =>
new
GGroup {ID = i, Name =
string
.Format(
"Group {0}"
, i)}).ToList();
foreach
(var gGroup
in
groups)
{
var sgroups = Enumerable.Range(0, 5).Select(i =>
new
SGroup {ID = i, Name =
string
.Format(
"SGroup {0}"
, i)}).ToList();
gGroup.Children.AddRange(sgroups);
}
depart.Children.AddRange(groups);
}
return
new
List<NomenclaturalUnit>(departs);
}
public
List<NomenclaturalUnit> GetProductsFromSGroup(
int
idSGroup)
{
// Each subgroup has 10 products
return
new
List<NomenclaturalUnit>(
Enumerable.Range(0, 10).Select(i =>
new
Product
{
ID = i,
Name =
string
.Format(
"Product {0}"
, i)
}));
}
}
- On the client side we have a simple Silverlight application (RadControlsSilverlightApp). Then I add Service Reference, so I have MODEL, in proxy-namespace RadControlsSilverlightApp1.MainServiceReference (see screenshot_1)
Then wrap our classes in UI-wrap-class, creating NomenclatureViewModel class. It class "represents" RadTreeViewItem. It contains a reference to NomenclaturalUnit (defined in WCF service, and, therefore in proxy-namespace), collection of child items of NomenclatureViewModel type and properties IsSelected, IsExpanded and IsLoadOnDemandEnabled. BTW, IsLoadOnDemandEnabled always False, except when NomenclaturalUnit is SGroup. (So, we have only 1 LOD-level - the third)
public
class
NomenclatureViewModel : ViewModelBase
{
public
NomenclaturalUnit NomenclaturalUnit {
get
;
protected
set
; }
public
ObservableCollection<NomenclatureViewModel> Children {
get
;
set
; }
public
NomenclatureViewModel(NomenclaturalUnit nomenclaturalUnit)
{
_isLoadOnDemandEnabled =
false
;
NomenclaturalUnit = nomenclaturalUnit;
Children =
new
ObservableCollection<NomenclatureViewModel>();
foreach
(var nomenclatureViewModel
in
nomenclaturalUnit.Children.Select(child =>
new
NomenclatureViewModel(child) { IsLoadOnDemandEnabled = child
is
SGroup }))
{
Children.Add(nomenclatureViewModel);
}
}
private
bool
_isLoadOnDemandEnabled;
public
virtual
bool
IsLoadOnDemandEnabled
{
get
{
return
_isLoadOnDemandEnabled; }
set
{
_isLoadOnDemandEnabled = value;
OnPropertyChanged(
"IsLoadOnDemandEnabled"
);
}
}
private
bool
_isSelected;
public
bool
IsSelected
{
get
{
return
_isSelected; }
set
{
if
(_isSelected != value)
{
_isSelected = value;
OnPropertyChanged(
"IsSelected"
);
}
}
}
private
bool
_isExpanded;
public
bool
IsExpanded
{
get
{
return
_isExpanded; }
set
{
if
(_isExpanded != value)
{
_isExpanded = value;
OnPropertyChanged(
"IsExpanded"
);
}
}
}
}
- Then I create ViewModel class, that will be an UI-wrap over the whole RadTreeView (its DataContext)
public
class
ViewModel : ViewModelBase
{
public
ViewModel()
{
SetupCommands();
NomenclatureCollection =
new
ObservableCollection<NomenclatureViewModel>();
}
#region Presentation Properties
public
ObservableCollection<NomenclatureViewModel> NomenclatureCollection {
get
;
set
; }
private
bool
_loadingOnDemand;
public
bool
LoadingOnDemand
{
get
{
return
_loadingOnDemand; }
set
{
if
(_loadingOnDemand != value)
{
_loadingOnDemand = value;
OnPropertyChanged(
"LoadingOnDemand"
);
}
}
}
#endregion
#region Setup Commanding
public
ICommand LoadedCommand {
get
;
set
; }
public
ICommand LoadOnDemandCommand {
get
;
set
; }
public
ICommand SelectCommand {
get
;
set
; }
private
void
SetupCommands()
{
LoadedCommand =
new
DelegateCommand(o => Loaded());
LoadOnDemandCommand =
new
RelayCommand<RadRoutedEventArgs>(LoadOnDemand, args =>
true
);
SelectCommand =
new
DelegateCommand(o => SelectItemInTree());
}
#endregion
#region Event Handlers
/// <summary>
/// Метод вызывает при наступления события Loaded главного окна
/// </summary>
private
void
Loaded()
{
var serviceClient =
new
RCPMainServiceClient();
serviceClient.GetProductNomenclatureCompleted +=
(sender, e) =>
{
foreach
(var item
in
e.Result)
{
NomenclatureCollection.Add(
new
NomenclatureViewModel(item));
}
};
serviceClient.GetProductNomenclatureAsync();
}
/// <summary>
/// Метод вызывается при наступлении события LoadOnDemand исходного RadTreeView (разворачивание узла)
/// </summary>
/// <param name="e">Параметры</param>
private
void
LoadOnDemand(RadRoutedEventArgs e)
{
var currentItem = e.OriginalSource
as
RadTreeViewItem;
if
(currentItem !=
null
)
{
var unitViewModel = currentItem.Item
as
NomenclatureViewModel;
if
(unitViewModel !=
null
&& unitViewModel.NomenclaturalUnit
is
SGroup)
{
var sGroup = unitViewModel.NomenclaturalUnit
as
SGroup;
var serviceClient =
new
RCPMainServiceClient();
serviceClient.GetProductsFromSGroupCompleted +=
(s, args) =>
{
foreach
(var item
in
args.Result)
{
sGroup.Children.Add(item);
}
foreach
(var nomenclatureViewModel
in
sGroup.Children.Select(child =>
new
NomenclatureViewModel(child)))
{
unitViewModel.Children.Add(nomenclatureViewModel);
}
e.Handled =
true
;
unitViewModel.IsLoadOnDemandEnabled =
false
;
LoadingOnDemand =
false
;
};
LoadingOnDemand =
true
;
serviceClient.GetProductsFromSGroupAsync((
int
)sGroup.ID);
}
}
}
#endregion
private
void
SelectItemInTree()
{
NomenclatureCollection[0].IsExpanded =
true
;
NomenclatureCollection[0].Children[0].IsExpanded =
true
;
var nomenclatureViewModel = NomenclatureCollection[0].Children[0].Children[0];
// ISSUE IS HERE -
nomenclatureViewModel.IsExpanded =
true
;
// ISSUE IS HERE
}
}
- And last but not least, I create in MainWindow 2 elements - RadTreeView and RadButton, that calls command "SelectCommand" in ViewModel.
Note, i use ContainerBindingCollection for set IsLoadOnDemandEnabled, IsSelected and IsExpanded propertyes in TwoWay mode.
<
UserControl
x:Class
=
"RadControlsSilverlightApp1.MainPage"
xmlns:MVVMLightCommand
=
"clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4"
xmlns:telerik
=
"http://schemas.telerik.com/2008/xaml/presentation"
xmlns:ViewModel
=
"clr-namespace:RadControlsSilverlightApp1.ViewModel"
d:DesignHeight
=
"800"
d:DesignWidth
=
"400"
mc:Ignorable
=
"d"
>
<
UserControl.Resources
>
<
ViewModel:ViewModel
x:Key
=
"dataSource"
/>
</
UserControl.Resources
>
<
Grid
>
<
Grid.Resources
>
<
telerik:ContainerBindingCollection
x:Name
=
"BindingsCollection"
>
<
telerik:ContainerBinding
Binding
=
"{Binding IsLoadOnDemandEnabled, Mode=TwoWay}"
PropertyName
=
"IsLoadOnDemandEnabled"
/>
<
telerik:ContainerBinding
Binding
=
"{Binding IsSelected, Mode=TwoWay}"
PropertyName
=
"IsSelected"
/>
<
telerik:ContainerBinding
Binding
=
"{Binding IsExpanded, Mode=TwoWay}"
PropertyName
=
"IsExpanded"
/>
</
telerik:ContainerBindingCollection
>
<
telerik:HierarchicalDataTemplate
x:Key
=
"NodeTemplate"
ItemsSource
=
"{Binding Children}"
telerik:ContainerBinding.ContainerBindings
=
"{StaticResource BindingsCollection}"
>
<
StackPanel
Orientation
=
"Horizontal"
>
<
TextBlock
Text
=
"{Binding NomenclaturalUnit.Name}"
/>
<
TextBlock
Text
=
" ["
/>
<
TextBlock
FontWeight
=
"Bold"
Text
=
"{Binding NomenclaturalUnit.ID}"
/>
<
TextBlock
Text
=
"]"
/>
</
StackPanel
>
</
telerik:HierarchicalDataTemplate
>
</
Grid.Resources
>
<
Grid.RowDefinitions
>
<
RowDefinition
Height
=
"Auto"
MinHeight
=
"25"
/>
<
RowDefinition
/>
</
Grid.RowDefinitions
>
<
StackPanel
>
<
telerik:RadButton
Content
=
"Expand in ViewModel"
FontWeight
=
"Bold"
Padding
=
"1"
>
<
i:Interaction.Triggers
>
<
i:EventTrigger
EventName
=
"Click"
>
<
MVVMLightCommand:EventToCommand
Command
=
"{Binding SelectCommand, Source={StaticResource dataSource}}"
/>
</
i:EventTrigger
>
</
i:Interaction.Triggers
>
</
telerik:RadButton
>
<
telerik:RadButton
Click
=
"RadButton_Click"
Content
=
"Expand from code-behind"
FontWeight
=
"Bold"
Padding
=
"1"
/>
</
StackPanel
>
<
telerik:RadTreeView
x:Name
=
"radTreeView"
Grid.Row
=
"1"
IsVirtualizing
=
"True"
ItemsSource
=
"{Binding NomenclatureCollection, Source={StaticResource dataSource}}"
ItemTemplate
=
"{StaticResource NodeTemplate}"
telerik:AnimationManager.IsAnimationEnabled
=
"False"
telerik:TextSearch.TextPath
=
"NomenclaturalUnit.ID"
telerik:TreeViewPanel.VirtualizationMode
=
"Recycling"
>
<
i:Interaction.Triggers
>
<
i:EventTrigger
>
<
i:InvokeCommandAction
Command
=
"{Binding LoadedCommand, Source={StaticResource dataSource}}"
/>
</
i:EventTrigger
>
<
i:EventTrigger
EventName
=
"LoadOnDemand"
>
<
MVVMLightCommand:EventToCommand
Command
=
"{Binding LoadOnDemandCommand, Source={StaticResource dataSource}}"
PassEventArgsToCommand
=
"True"
/>
</
i:EventTrigger
>
</
i:Interaction.Triggers
>
</
telerik:RadTreeView
>
</
Grid
>
</
UserControl
>
- The code shows the place where I find the problem. Trigger "LoadOnDemand" is not called, although it called on mouse click. We have the problem exactly at LOD item. Others nodes, not LOD-items, are expanded well. Note that if you call the same action from code-behind (it couldn't be done in my application becouse all logic has to be in the ViewModel because of specified reasons) - everything will work, as I mentioned in my previous message.
Thank you and again and I so sorry for my English =)
P.S. I can not attach my solution...
0
Hello Doxxer,
but you haven't bound it. Why not make this property 9 or similar one) part of NomenclatureViewModel and bind it to the IsLoadingOnDemand property of the RadTreeViewitem via ContainerBindings? Usually, in non-MVVM scenarios this property has to be set after the loading completes. Please let us know if this helped you.
Best wishes,
Petar Mladenov
the Telerik team
We can see that you set the LoadingOnDemand to false when the Load operation completes:
serviceClient.GetProductsFromSGroupCompleted +=
(s, args) =>
{
foreach
(var item
in
args.Result)
{
sGroup.Children.Add(item);
}
foreach
(var nomenclatureViewModel
in
sGroup.Children.Select(child =>
new
NomenclatureViewModel(child)))
{
unitViewModel.Children.Add(nomenclatureViewModel);
}
e.Handled =
true
;
unitViewModel.IsLoadOnDemandEnabled =
false
;
LoadingOnDemand =
false
;
};
Petar Mladenov
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
Niladri
Top achievements
Rank 1
answered on 29 Nov 2011, 11:08 AM
Hello,
I am newbie to the Silverlight. So, my question may look very silly to experienced guys, but believe me, I need your help to sort tis out.
I have the following in my XAML
And here is EventToCommand
When I am running the project I am getting the following error:
The type 'EventToCommand' was not found because 'clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4' is an unknown namespace.
And here is the full snippet of the CheckBox column
Please help me ! Thanks in advance,
Best regards,
Niladri
I am newbie to the Silverlight. So, my question may look very silly to experienced guys, but believe me, I need your help to sort tis out.
I have the following in my XAML
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4">
And here is EventToCommand
<cmd:EventToCommand Command="{Binding SelectTimeStudyCommand}" PassEventArgsToCommand="True" />
When I am running the project I am getting the following error:
The type 'EventToCommand' was not found because 'clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.SL4' is an unknown namespace.
And here is the full snippet of the CheckBox column
<telerik:GridViewCheckBoxColumn DataMemberBinding="{Binding Path=IsSelected}" Header="Select"> <i:Interaction.Triggers> <i:EventTrigger EventName="PropertyChanged"> <cmd:EventToCommand Command="{Binding SelectTimeStudyCommand}" PassEventArgsToCommand="True" /> </i:EventTrigger> </i:Interaction.Triggers> </telerik:GridViewCheckBoxColumn>
Please help me ! Thanks in advance,
Best regards,
Niladri
0
Jimmy
Top achievements
Rank 1
answered on 01 Dec 2011, 02:49 AM
Hi,
I am having (maybe similar) problem on expanding a load-on-demand treeview item from the ViewModel. I have the IsExpanded property of the RadTreeViewItem binding setup as TwoWay. After IsExpanded is set to true in the ViewModel, the load on demand logic is triggered but visually, the item's Expander just spans and the item never gets expanded - see attached.
The attached screenshot is produced based on the code TreeViewContainerBindings.zip from
http://www.telerik.com/community/forums/silverlight/treeview/opening-treeview-in-expanded-mode.aspx with updates on the following three files.
Start the app and click on the "Expand Item 3" button will reproduce the behavior shown on the attached screen shot. What am I missing to make the item expand?
Thanks.
1. MainPage.xaml
2. ViewModel.cs
3. DataItem.cs
I am having (maybe similar) problem on expanding a load-on-demand treeview item from the ViewModel. I have the IsExpanded property of the RadTreeViewItem binding setup as TwoWay. After IsExpanded is set to true in the ViewModel, the load on demand logic is triggered but visually, the item's Expander just spans and the item never gets expanded - see attached.
The attached screenshot is produced based on the code TreeViewContainerBindings.zip from
http://www.telerik.com/community/forums/silverlight/treeview/opening-treeview-in-expanded-mode.aspx with updates on the following three files.
Start the app and click on the "Expand Item 3" button will reproduce the behavior shown on the attached screen shot. What am I missing to make the item expand?
Thanks.
1. MainPage.xaml
<
UserControl.Resources
>
<
telerik:ContainerBindingCollection
x:Key
=
"TreeBindingsCollection"
>
<
telerik:ContainerBinding
Binding
=
"{Binding IsExpanded, Mode=TwoWay}"
PropertyName
=
"IsExpanded"
/>
<
telerik:ContainerBinding
Binding
=
"{Binding IsLoadingOnDemand}"
PropertyName
=
"IsLoadingOnDemand"
/>
<
telerik:ContainerBinding
Binding
=
"{Binding IsLoadOnDemandEnabled}"
PropertyName
=
"IsLoadOnDemandEnabled"
/>
</
telerik:ContainerBindingCollection
>
<
telerik:HierarchicalDataTemplate
x:Key
=
"ItemTemplate"
ItemsSource
=
"{Binding Children}"
telerik:ContainerBinding.ContainerBindings
=
"{StaticResource TreeBindingsCollection}"
>
<
TextBlock
Text
=
"{Binding Header}"
/>
</
telerik:HierarchicalDataTemplate
>
</
UserControl.Resources
>
<
UserControl.DataContext
>
<
local:ViewModel
/>
</
UserControl.DataContext
>
<
Grid
>
<
Grid.RowDefinitions
>
<
RowDefinition
Height
=
"40"
></
RowDefinition
>
<
RowDefinition
Height
=
"*"
></
RowDefinition
>
</
Grid.RowDefinitions
>
<
telerik:RadButton
Content
=
"Expand Item 3"
Command
=
"{Binding ExpandItemCommand}"
Grid.Row
=
"0"
>
</
telerik:RadButton
>
<
telerik:RadTreeView
x:Name
=
"radTreeView"
IsLoadOnDemandEnabled
=
"True"
SelectedItem
=
"{Binding SelectedItem, Mode=TwoWay}"
ItemTemplate
=
"{StaticResource ItemTemplate}"
ItemsSource
=
"{Binding Items}"
IsExpandOnSingleClickEnabled
=
"True"
Grid.Row
=
"1"
>
<
i:Interaction.Triggers
>
<
i:EventTrigger
EventName
=
"LoadOnDemand"
>
<
i:InvokeCommandAction
Command
=
"{Binding ItemExpandedCommand}"
CommandParameter
=
"{Binding SelectedItem.Header}"
/>
</
i:EventTrigger
>
<
i:EventTrigger
EventName
=
"ItemPrepared"
>
<
i:InvokeCommandAction
Command
=
"{Binding ItemPreparedCommand}"
/>
</
i:EventTrigger
>
</
i:Interaction.Triggers
>
</
telerik:RadTreeView
>
</
Grid
>
2. ViewModel.cs
using
System;
using
System.Net;
using
System.Windows;
using
System.Windows.Controls;
using
System.Windows.Documents;
using
System.Windows.Ink;
using
System.Windows.Input;
using
System.Windows.Media;
using
System.Windows.Media.Animation;
using
System.Windows.Shapes;
using
Telerik.Windows.Controls;
using
System.Collections.ObjectModel;
namespace
_314398_TreeViewExample
{
public
class
ViewModel : ViewModelBase
{
public
ViewModel()
{
ItemExpandedCommand =
new
DelegateCommand((a) => {
this
.LoadOnDemandCommand(a.ToString()); }, (p) => {
return
true
; });
ItemPreparedCommand =
new
DelegateCommand((a) => { }, (p) => {
return
true
; });
ExpandItemCommand =
new
DelegateCommand((a) => {
this
.ExpandItem(); }, (p) => {
return
true
; });
Items =
new
ObservableCollection<DataItem>();
for
(
int
i = 0; i < 8; i++)
{
DataItem item =
new
DataItem()
{
Header = String.Format(
"Item {0}"
, i), IsLoadOnDemandEnabled =
true
};
Items.Add(item);
}
this
.SelectedItem =
this
.Items[0];
}
private
DataItem selectedItem;
public
DataItem SelectedItem
{
get
{
return
this
.selectedItem;
}
set
{
if
(
this
.selectedItem != value)
{
this
.selectedItem = value;
OnPropertyChanged(
"SelectedItem"
);
}
}
}
public
DelegateCommand ItemExpandedCommand {
get
;
set
; }
public
DelegateCommand ItemPreparedCommand {
get
;
set
; }
public
DelegateCommand ExpandItemCommand {
get
;
set
; }
private
void
LoadOnDemandCommand(
string
param)
{
foreach
(DataItem item
in
Items)
{
if
(item.Header == param)
{
for
(
int
i = 0; i < 5; i++)
{
item.Children.Add(
new
DataItem() { Header = String.Format(
"{0}.{1}"
, item.Header, i), IsLoadingOnDemand =
false
});
}
item.IsLoadingOnDemand =
false
;
}
}
}
private
void
ExpandItem()
{
foreach
(DataItem item
in
Items)
{
if
(item.Header ==
"Item 3"
)
{
// this does triggers LoadOnDemandCommand, but the treeItem doesn't expand.
item.IsExpanded =
true
;
}
}
}
public
ObservableCollection<DataItem> Items {
get
;
set
; }
}
}
3. DataItem.cs
using
System;
using
System.Net;
using
System.Windows;
using
System.Windows.Controls;
using
System.Windows.Documents;
using
System.Windows.Ink;
using
System.Windows.Input;
using
System.Windows.Media;
using
System.Windows.Media.Animation;
using
System.Windows.Shapes;
using
System.Collections.ObjectModel;
using
System.ComponentModel;
using
Telerik.Windows.Controls;
namespace
_314398_TreeViewExample
{
public
class
DataItem : ViewModelBase
{
public
DataItem()
{
this
.Children =
new
ObservableCollection<DataItem>();
}
private
bool
isLoadOnDemandEnabled;
public
bool
IsLoadOnDemandEnabled
{
get
{
return
this
.isLoadOnDemandEnabled;
}
set
{
if
(
this
.isLoadOnDemandEnabled != value)
{
this
.isLoadOnDemandEnabled = value;
OnPropertyChanged(
"IsLoadOnDemandEnabled"
);
}
}
}
private
bool
isLoadingOnDemand;
public
bool
IsLoadingOnDemand
{
get
{
return
this
.isLoadingOnDemand;
}
set
{
if
(
this
.isLoadingOnDemand != value)
{
this
.isLoadingOnDemand = value;
OnPropertyChanged(
"IsLoadingOnDemand"
);
}
}
}
private
bool
isExpanded;
public
bool
IsExpanded
{
get
{
return
this
.isExpanded;
}
set
{
if
(
this
.isExpanded != value)
{
this
.isExpanded = value;
OnPropertyChanged(
"IsExpanded"
);
}
}
}
private
string
header;
public
string
Header
{
get
{
return
this
.header;
}
set
{
if
(
this
.header != value)
{
this
.header = value;
OnPropertyChanged(
"Header"
);
}
}
}
public
ObservableCollection<DataItem> Children {
get
;
set
; }
}
}
0
Hi guys,
@Niladri - Unfortunately I cannot be sure what is causing this exception based only on the code snippets you sent. Can you try to isolate the issue in a small sample and send it to us? Also, in this forum thread you can find a sample solution using EventToCommand to implement an MVVM approach for customize the DragDrop behavior of the RadTreeView. The solution might help you find the cause for the exception in your project.
@Jimmy - Thank you for sending your code. While I examined it I noticed that the LoadOnDemandCommand receives the header of the selected RadTreeViewItem as a parameter. However, when you click the Expand button, the selected item still remains the first item in the RadTreeview control. And then the LoadOnDemand logic tries to expand the 3rd item, while popupating the 1st RadTreeViewItems.ItemsSource colelction. This is why you get the loading animation which cannot end as the 3rd RadTreeViweItem.ItemsSource collection is never populated. Basically you need to make sure in your scenario, that the item that will be expanded is also selected. For example you can create an IsSelected property in the DataItem class and bind the RadTreeViewItem.IsSelected property to it:
Then you can set the DataItems IsSelected property to True before setting their IsExpanded property to true.
I hope this information helps. But please let me know if you have more questions.
Regards,
Tina Stancheva
the Telerik team
@Niladri - Unfortunately I cannot be sure what is causing this exception based only on the code snippets you sent. Can you try to isolate the issue in a small sample and send it to us? Also, in this forum thread you can find a sample solution using EventToCommand to implement an MVVM approach for customize the DragDrop behavior of the RadTreeView. The solution might help you find the cause for the exception in your project.
@Jimmy - Thank you for sending your code. While I examined it I noticed that the LoadOnDemandCommand receives the header of the selected RadTreeViewItem as a parameter. However, when you click the Expand button, the selected item still remains the first item in the RadTreeview control. And then the LoadOnDemand logic tries to expand the 3rd item, while popupating the 1st RadTreeViewItems.ItemsSource colelction. This is why you get the loading animation which cannot end as the 3rd RadTreeViweItem.ItemsSource collection is never populated. Basically you need to make sure in your scenario, that the item that will be expanded is also selected. For example you can create an IsSelected property in the DataItem class and bind the RadTreeViewItem.IsSelected property to it:
<
telerik:ContainerBindingCollection
x:Key
=
"TreeBindingsCollection"
>
<
telerik:ContainerBinding
Binding
=
"{Binding IsExpanded, Mode=TwoWay}"
PropertyName
=
"IsExpanded"
/>
<
telerik:ContainerBinding
Binding
=
"{Binding IsSelected, Mode=TwoWay}"
PropertyName
=
"IsSelected"
/>
<
telerik:ContainerBinding
Binding
=
"{Binding IsLoadingOnDemand}"
PropertyName
=
"IsLoadingOnDemand"
/>
<
telerik:ContainerBinding
Binding
=
"{Binding IsLoadOnDemandEnabled}"
PropertyName
=
"IsLoadOnDemandEnabled"
/>
</
telerik:ContainerBindingCollection
>
I hope this information helps. But please let me know if you have more questions.
Regards,
Tina Stancheva
the Telerik team
Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
0
Jimmy
Top achievements
Rank 1
answered on 03 Dec 2011, 05:55 AM
@Tina, it works. Thank you.