Is there a way to sort a WPF DataGrid programmaticaly ( for example, like if i clicked on my first column).
Is there a way to simuate this click ? Or a best way ?
voo's solution was not working for me, ItemsSource
was null, most likely because it was not directly set, but bound.
All other solutions I found here at StackOverflow were dealing with sorting the Model only, but the DataGrid
header was not reflecting to the sort.
Here's a proper solution based on the incomplete script here: http://dotnetgui.blogspot.co.uk/2011/02/how-to-properly-sort-on-wpf-datagrid.html
public static void SortDataGrid(DataGrid dataGrid, int columnIndex = 0, ListSortDirection sortDirection = ListSortDirection.Ascending)
{
var column = dataGrid.Columns[columnIndex];
// Clear current sort descriptions
dataGrid.Items.SortDescriptions.Clear();
// Add the new sort description
dataGrid.Items.SortDescriptions.Add(new SortDescription(column.SortMemberPath, sortDirection));
// Apply sort
foreach (var col in dataGrid.Columns)
{
col.SortDirection = null;
}
column.SortDirection = sortDirection;
// Refresh items to display sort
dataGrid.Items.Refresh();
}
In case of your code, it can be used like this:
SortDataGrid(myDataGridEvenements, 0, ListSortDirection.Ascending);
Or by using the default parameter values, simply:
SortDataGrid(myDataGridEvenements);
PerformSort method of the DataGrid is what actually executed on a column's header click. However this method is internal. So if you really want to simulate the click you need to use reflection:
public static void SortColumn(DataGrid dataGrid, int columnIndex)
{
var performSortMethod = typeof(DataGrid)
.GetMethod("PerformSort",
BindingFlags.Instance | BindingFlags.NonPublic);
performSortMethod?.Invoke(dataGrid, new[] { dataGrid.Columns[columnIndex] });
}
My method is work for me. Just try this code. Sorry for Russian
// Если таблица пустая, то привязываем ее к журналу
if(dgEvents.ItemsSource == null)
dgEvents.ItemsSource = events.Entries;
// Обновляем записи
CollectionViewSource.GetDefaultView(dgEvents.ItemsSource).Refresh();
// Очищаем описание сортировки
dgEvents.Items.SortDescriptions.Clear();
// Созадем описание сортировки
dgEvents.Items.SortDescriptions.Add(new SortDescription(dgEvents.Columns[0].SortMemberPath, ListSortDirection.Descending));
// Очищаем сортировку всех столбцов
foreach (var col in dgEvents.Columns)
{
col.SortDirection = null;
}
// Задаем сортировку времени по убыванию (последняя запись вверху)
dgEvents.Columns[0].SortDirection = ListSortDirection.Descending;
// Обновляем записи
dgEvents.Items.Refresh();
Fast & Easy way:
dgv.Items.SortDescriptions.Clear();
dgv.Items.SortDescriptions.Add(new SortDescription("ID", ListSortDirection.Descending));
dgv.Items.Refresh();
you can use ICollectionView to filter, sort and group your items in a datagrid.
EDIT: add Sort, did not read the question carefully :)
var view = CollectionViewSource.GetDefaultView(this.MyData);
view.Filter = ViewFilter;
view.SortDescriptions.Add(new SortDescription("MyPropertyToSort", ListSortDirection.Descending));
private bool ViewFilter(object obj)
{
var item = obj as MyObject;
if (item == null)
return false;
//your filter logik goes here
if(item.MyStringProp.StartsWith("Test"))
return false;
return true;
}
Get your ItemsSource's DataView and use its Sort property to specify the column you are sorting by:
(yourDataGrid.ItemsSource as DataView).Sort = "NAME_OF_COLUMN";