Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

WPF DataGrid: Automatically re-sort on a DataGridTemplateColumn

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"); } }
}
like image 682
Joel Rein Avatar asked Oct 24 '10 12:10

Joel Rein


2 Answers

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.

like image 59
Kelly Avatar answered Oct 25 '22 10:10

Kelly


I know this is old but also I got this DataGridTemplateColumn re-sort problem. This does not happen on DataGridTextColumn. The way I fix it with intact sort direction on column header is:

// after updating the collection, remove all SortDescription and add'em back.
SortDescriptionCollection sortDescriptions = new SortDescriptionCollection();
foreach (SortDescription sd in dataGrid.Items.SortDescriptions)
{
    sortDescriptions.Add(sd);
}
dataGrid.Items.SortDescriptions.Clear();

foreach (SortDescription sd in sortDescriptions)
{
    dataGrid.Items.SortDescriptions.Add(sd);
}

Hope this helps people.

like image 41
Peter Avatar answered Oct 25 '22 10:10

Peter