How To: Hierarchy Load On Demand With RadTreeView for Silverlight, MVVM and OData

Tuesday, October 26, 2010 by XAML Team | Comments 0

Similar to this post, I’ve made a similar example on how to load on demand RadTreeView for Silverlight three level hierarchy using MVVM and OData service: 

XAML 

<UserControl.Resources>
    <DataTemplate x:Key="OrderDetailsTemplate">
        <Grid>
           ...
        </Grid>
    </DataTemplate>
    <telerik:HierarchicalDataTemplate x:Key="OrderTemplate"
            ItemsSource="{Binding OrderDetailsCollection}"
            ItemTemplate="{StaticResource OrderDetailsTemplate}">
        <StackPanel Orientation="Horizontal">
           ...
        </StackPanel>
    </telerik:HierarchicalDataTemplate>
    <telerik:HierarchicalDataTemplate x:Key="CompanyTemplate"
            ItemsSource="{Binding OrdersCollection}"
            ItemTemplate="{StaticResource OrderTemplate}">
        <StackPanel Orientation="Horizontal">
           ...
        </StackPanel>
    </telerik:HierarchicalDataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot" Background="White">
    <telerik:RadTreeView x:Name="treeView1" ItemsSource="{Binding CustomersCollection}"
            ItemTemplate="{StaticResource CompanyTemplate}" />
</Grid>

C#

public partial class MainPage : UserControl
{
    public MainPage()
    {
        InitializeComponent();
 
        DataContext = new NorthwindEntities();
    }
}

The approach is the same as in the RadGridView post. Again, I’ve used partial classes to extend generated code for the service reference:

C#

public partial class NorthwindEntities
{
    public NorthwindEntities()
        : base(new Uri("http://services.odata.org/Northwind/Northwind.svc"))
    {
        //
    }
 
    DataServiceCollection<Customer> _CustomersCollection;
    public DataServiceCollection<Customer> CustomersCollection
    {
        get
        {
            if (_CustomersCollection == null)
            {
                _CustomersCollection = new DataServiceCollection<Customer>(this);
                _CustomersCollection.CollectionChanged += (s, e) =>
                {
                    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                    {
                        foreach (var c in e.NewItems.OfType<Customer>())
                        {
                            c.Context = this;
                        }
                    }
                    else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
                    {
                        foreach (var c in e.OldItems.OfType<Customer>())
                        {
                            c.Context = null;
                        }
                    }
                };
                _CustomersCollection.LoadAsync(this.Customers);
            }
            return _CustomersCollection;
        }
    }
}

and as you can see I’ve passed the context itself to the entities in order to create queries for child data:

C#

public partial class Customer
{
    public Customer()
    {
        _Orders = null;
    }
 
    internal NorthwindEntities Context { get; set; }
 
    public DataServiceCollection<Order> OrdersCollection
    {
        get
        {
            if (_Orders == null && Context != null)
            {
                _Orders = new DataServiceCollection<Order>(Context);
                _Orders.CollectionChanged += (s, e) =>
                {
                    if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Add)
                    {
                        foreach (var c in e.NewItems.OfType<Order>())
                        {
                            c.Context = this.Context;
                        }
                    }
                    else if (e.Action == System.Collections.Specialized.NotifyCollectionChangedAction.Remove)
                    {
                        foreach (var c in e.OldItems.OfType<Order>())
                        {
                            c.Context = null;
                        }
                    }
                };
                _Orders.LoadAsync(from o in Context.Orders
                                    where o.CustomerID == CustomerID
                                    select o);
            }
            return _Orders;
        }
    }
}

Demo: TreeView, MVVM and OData

In addition, you can check our online TreeView OData example.

Add comment

  1. Formatting options
       
     
     
     
     
       
  2. (optional, emails won't be shown on public pages)
  3. (optional)