Similar to this post, I’ve made small example on how to load on demand RadGridView for Silverlight three level hierarchy using MVVM and OData service:
XAML
<telerik:RadGridView ItemsSource="{Binding CustomersCollection}" AutoGenerateColumns="False"> <telerik:RadGridView.Columns> …
</telerik:RadGridView.Columns> <telerik:RadGridView.ChildTableDefinitions> <telerik:GridViewTableDefinition /> </telerik:RadGridView.ChildTableDefinitions> <telerik:RadGridView.HierarchyChildTemplate> <DataTemplate> <telerik:RadGridView ItemsSource="{Binding OrdersCollection}" AutoGenerateColumns="False"> <telerik:RadGridView.Columns> …
</telerik:RadGridView.Columns> <telerik:RadGridView.ChildTableDefinitions> <telerik:GridViewTableDefinition /> </telerik:RadGridView.ChildTableDefinitions> <telerik:RadGridView.HierarchyChildTemplate> <DataTemplate> <telerik:RadGridView ItemsSource="{Binding OrderDetailsCollection}" AutoGenerateColumns="False"> <telerik:RadGridView.Columns> …
</telerik:RadGridView.Columns> </telerik:RadGridView> </DataTemplate> </telerik:RadGridView.HierarchyChildTemplate> </telerik:RadGridView> </DataTemplate> </telerik:RadGridView.HierarchyChildTemplate> </telerik:RadGridView>
C#
public partial class MainPage : UserControl { public MainPage() { InitializeComponent(); DataContext = new NorthwindEntities(); } }
I’ve used again 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; } } }
Vladimir Enchev is Director of Engineering, Native Mobile UI & Frameworks