Tuesday, September 28, 2010
by
Vladimir Enchev
|
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;
}
}
}