How to apply sorting to ObservableCollection and DataGrid

BitSmithy 1,771 Reputation points
2022-01-21T15:12:13.5+00:00

Hello,

I have UWP DataGrid and ObservableCollection:

            <controls:DataGrid x:Name="dgTableView" Margin="0,5,0,0"
                       CanUserSortColumns="True"
                       AutoGenerateColumns="True"
                       AutoGeneratingColumn="dgTableView_AutoGeneratingColumn"
                       Sorting="dgTableView_Sorting"
                               ></controls:DataGrid>

ObservableCollection<DataRow> dataTable = new ObservableCollection<DataRow>();
dgTableView.ItemsSource = dataTable;

Now I want to apply sorting in sorting event, but I dont want to trigger dgTableView_AutoGeneratingColumn, so I cant change dgTableView.ItemsSource

I tried:

private void dgTableView_Sorting(object sender, Microsoft.Toolkit.Uwp.UI.Controls.DataGridColumnEventArgs e)
    {

dataTable = new ObservableCollection<>(dataTable.OrderBy(x => x.c0))

}

But those have no effect. How to apply sorting to dataTable without changing ItemsSource, and show it in DataGrid

Below DataRow Class which feeds ObservableCollection:

    public class DataRow : INotifyPropertyChanged
    {
        public string c0 { get; set; } = "";
        public string c1 { get; set; } = "";

}

Universal Windows Platform (UWP)
0 comments No comments
{count} votes

Accepted answer
  1. Roy Li - MSFT 32,231 Reputation points Microsoft Vendor
    2022-01-24T07:12:15.583+00:00

    Hello,

    Welcome to Microsoft Q&A!

    So you want to trigger the Sorting event but you don't want the AutoGeneratingColumn event is triggered, is that right?

    I'd suggest you using the AdvancedCollectionView from the Microsoft.Toolkit.Uwp.UI NuGet package as the itemssource instead of directly using the ObservableCollection. The AdvancedCollectionView is a collection view implementation that support filtering, sorting. It could finish the soring work just in the code behind and notify the UI to update. In your scenario, it won't trigger the AutoGeneratingColumn event.

    Steps:

    Here are the steps that you could follow:

    1. Install the Microsoft.Toolkit.Uwp.UI NuGet Package, add using Microsoft.Toolkit.Uwp.UI; into code.
    2. Create a AdvancedCollectionView object from the ObservableCollection<DataRow> object.
    3. Use the AdvancedCollectionView object as the ItemsSource of the DataGrid.
    4. In the Sorting event, using the built-in sorting function of the AdvancedCollectionView object.

    Sample:

    I've made a simple demo to show the specific steps about the usage of AdvancedCollectionView

    Xaml:

       <controls:DataGrid x:Name="dataGrid1"   
                               Height="600" Margin="12"  
                               AutoGenerateColumns="True"   
                               AutoGeneratingColumn="dataGrid1_AutoGeneratingColumn"  
                               ItemsSource="{x:Bind MyViewModel.Customers}"   
                               Sorting="dataGrid1_Sorting"  
                               CanUserSortColumns="True"/>  
    

    Code-behind:

        public sealed partial class MainPage : Page  
        {  
            public ViewModel MyViewModel { get; set; }  
            public MainPage()  
            {  
                this.InitializeComponent();  
                MyViewModel = new ViewModel();  
            }  
      
            private void dataGrid1_Sorting(object sender, DataGridColumnEventArgs e)  
            {  
                //Use the header property to pass the bound column name for the sorting implementation  
                if (e.Column.Header.ToString() == "Age")  
                {  
                    //Implement sort   
                    if (e.Column.SortDirection == null || e.Column.SortDirection == DataGridSortDirection.Descending)  
                    {  
                        //Clear pervious sorting    
                        MyViewModel.Customers.SortDescriptions.Clear();  
                        MyViewModel.Customers.SortDescriptions.Add(new SortDescription("Age", SortDirection.Ascending));  
      
                        e.Column.SortDirection = DataGridSortDirection.Ascending;  
                    }  
                    else  
                    {  
                        MyViewModel.Customers.SortDescriptions.Clear();  
                        MyViewModel.Customers.SortDescriptions.Add(new SortDescription("Age", SortDirection.Descending));  
                        e.Column.SortDirection = DataGridSortDirection.Descending;  
                    }  
                }  
            }  
      
            private void dataGrid1_AutoGeneratingColumn(object sender, DataGridAutoGeneratingColumnEventArgs e)  
            {  
                Debug.WriteLine("dataGrid1_AutoGeneratingColumn");  
            }  
        }  
      
        public class ViewModel   
        {  
            public AdvancedCollectionView Customers { get; set; }  
      
            //public ObservableCollection<Customer> Customers { get; set; }  
      
            public ViewModel()  
            {  
                ObservableCollection<Customer> oc = Customer.Customers();  
      
                Customers = new AdvancedCollectionView(oc, true);  
      
            }  
        }  
      
        public class Customer  
        {  
            public String FirstName { get; set; }  
            public String LastName { get; set; }  
            public String Address { get; set; }  
            public Boolean IsNew { get; set; }  
            public int Age { get; set; }  
      
            public Customer(String firstName, String lastName,  
                String address, Boolean isNew, int age)  
            {  
                this.FirstName = firstName;  
                this.LastName = lastName;  
                this.Address = address;  
                this.IsNew = isNew;  
                this.Age = age;  
            }  
      
            public static ObservableCollection<Customer> Customers()  
            {  
                return new ObservableCollection<Customer>(new Customer[4] {  
                new Customer("A.", "Zero",  
                    "12 North Third Street, Apartment 45",  
                    false,5),  
                new Customer("B.", "One",  
                    "34 West Fifth Street, Apartment 67",  
                    false,3),  
                new Customer("C.", "Two",  
                    "56 East Seventh Street, Apartment 89",  
                    true,6),  
                new Customer("D.", "Three",  
                    "78 South Ninth Street, Apartment 10",  
                    true,1)  
            });  
            }  
        }  
    

    Thank you.


    If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
    Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.

    0 comments No comments

0 additional answers

Sort by: Most helpful