WPF DataGrid: Automatically re-sort on a DataGridTemplateColumn

Jivlain picture Jivlain · Oct 24, 2010 · Viewed 17k times · Source

In WPF's DataGrid control, if you set a column to one of the default column types (like DataGridTextColumn or DataGridCheckBoxColumn), sort on that column, and then change its value, the grid will automatically be re-sorted.

However, if you use a DataGridTemplateColumn (and allow the column to be sorted), it can be sorted, but changing the value of a cell in this column does not cause the grid is not re-sorted. How can I coax it into automatically triggering a re-sort?

XAML:

<DataGrid Name="grid" AutoGenerateColumns="False">
  <DataGrid.Columns>
    <DataGridTextColumn Header="First name" Binding="{Binding First}"/>
    <DataGridTemplateColumn Header="Last name" SortMemberPath="Last">
      <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
          <TextBox Text="{Binding Last}"/>
        </DataTemplate>
      </DataGridTemplateColumn.CellTemplate>
    </DataGridTemplateColumn>
  </DataGrid.Columns>
</DataGrid>

Binding:

ObservableCollection items = new ObservableCollection();
grid.ItemsSource = items;
items.Add(new Character() { First = "Homer", Last = "Simpson" });
items.Add(new Character() { First = "Kent", Last = "Brockman" });
items.Add(new Character() { First = "Montgomery", Last = "Burns" });

Here's my item class, just in case that's relevant:

public class Character : INotifyPropertyChanged {
    private string first, last;
    public event PropertyChangedEventHandler PropertyChanged;
    private void Notify(string name) {
        if (PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(name));
    }
    public string First { get { return first; } set { first = value; Notify("First"); } }
    public string Last { get { return last; } set { last = value; Notify("Last"); } }
}

Answer

Kelly picture Kelly · Jun 27, 2011

I'm also looking the answer to this. I found one solution: (not happy with it but...)

When your collection is updated you can do this:

SortDescription sortDescription = grdData.Items.SortDescriptions[0];
grdData.ItemsSource = null;
grdData.ItemsSource = Data;
grdData.Items.SortDescriptions.Add(sortDescription);

Ugly but it does work. You will want to store the whole collection unlike my example that does just first item.

One problem with it though is that the DataGrid looses the header that indicates the sort, so although it resorts correctly the column header is no longer selected with the arrow showing the direction of the sort.