Sorting nested collections

Lets say we retrieve data which has nested property which is a collection(customer entity having bunch of orders). there are many ways to sort the returned collection of orders.

here is one way

we will have some code like below to get the list of customers, where we are including the Orders also, instead of changing the methods we could you CollectionViewSource to do the sorting

public IQueryable GetCustomers()
{
return this.ObjectContext.Customers.Include(“Orders”);
}

In the following sample, we are binding the collectionviewsource to the selected customers orders collection and sorting by orderdate, and binding ordersDatagrid to the CollectionViewSource

 we get the customers using

ctx.Load<Customer>(ctx.GetCustomersQuery(), (lo) => { customers = lo.Entities.ToList(); datagrid1.ItemsSource = customers; }, null);

  <UserControl.Resources>
        <CollectionViewSource x:Name=”cvs” Source=”{Binding ElementName=datagrid1, Path=SelectedItem.Orders}”>
            <CollectionViewSource.SortDescriptions>
                <scm:SortDescription PropertyName=”OrderDate” Direction=”Descending”/>
            </CollectionViewSource.SortDescriptions>
        </CollectionViewSource>
       
    </UserControl.Resources>

    <Grid x:Name=”LayoutRoot” Background=”White”>
        <Grid.RowDefinitions>
            <RowDefinition Height=”*”/>         
            <RowDefinition Height=”Auto”/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition/>
            <ColumnDefinition/>
        </Grid.ColumnDefinitions>
        <my:DataGrid x:Name=”datagrid1″ IsReadOnly=”True” Grid.Row=”0″ Grid.Column=”0″></my:DataGrid>                
        <my:DataGrid x:Name=”ordersDatagrid” ItemsSource=”{Binding Source={StaticResource cvs}}” Grid.Column=”1″/>
     
    </Grid>

SL4: DataGrid and contextmenu

There is a nice implementation of contextmenu by Jesse Bishop in SL4. It supports commands as well as click handlers
we could use that control and add context sensitive contextmenu to datagrid

I created a basic application, Here is the xaml for the mainpage. we have a datagrid which is bound to a list of persons

<UserControl xmlns:my=”clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data”  x:Class=”SilverlightApplication1.MainPage”
    xmlns=”http://schemas.microsoft.com/winfx/2006/xaml/presentation
    xmlns:x=”http://schemas.microsoft.com/winfx/2006/xaml
    xmlns:d=”http://schemas.microsoft.com/expression/blend/2008
    xmlns:mc=”http://schemas.openxmlformats.org/markup-compatibility/2006
             xmlns:menu=”clr-namespace:ContextMenuControls;assembly=ContextMenuControls”   
    mc:Ignorable=”d”
    d:DesignHeight=”300″ d:DesignWidth=”400″>

    <Grid x:Name=”LayoutRoot” Background=”White”>
<my:DataGrid x:Name=”datagrid1″ ItemsSource=”{Binding Persons}”></my:DataGrid>
    </Grid>
</UserControl>

when the rightmouse button is down on the grid. we do a hit test to get the row( the person item that was clicked), create a menuitem with person’s name and add to the Items of the contextmenu
when the item is clicked we remove the person from the list

void datagrid1_MouseRightButtonUp(object sender, MouseButtonEventArgs e)
{
IEnumerable elements = VisualTreeHelper.FindElementsInHostCoordinates(e.GetPosition(LayoutRoot), datagrid1);
DataGridRow row = null;
foreach (UIElement ele in elements)
{
if (ele is DataGridRow)
{
row = ele as DataGridRow;
break;
}
}

ContextMenu cm = new ContextMenu();
Person p = row.DataContext as Person;
MenuItem mi = new MenuItem { Text = “Delete ” + p.FirstName, Tag=p };
mi.Click += new MenuItem.ClickHandler(mi_Click);
cm.Items.Add(mi);

datagrid1.SetValue(ContextMenu.ContextMenuProperty, cm);
cm.IsOpen = true;

}

void mi_Click(object sender, EventArgs e)
{
Persons.Remove((sender as MenuItem).Tag as Person);
}

you can download the sample here