question

PaulaMorgan-3461 avatar image
0 Votes"
PaulaMorgan-3461 asked ·

[UWP][C#] - Datagrid ItemsSource

How can I bind a DataGrid's ItemsSource to list or array when I do not know the structure of the data? I know the column and row counts, but I need to create the object at run time that will bind to the Data grid.

Thanks for any suggestions.

Paula

windows-uwp
· 8
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.

If you already have the data Models just don't know which one will be used for the ItemsSource, you could use DataTemplateSelector to select correct DateTemplate. In this scenario, you could define the DateTemplates in XAML.

If your model is dynamically generated, you need to create a DataTemplate in code. Please provide more details so we can keep moving.

0 Votes 0 · ·

Thanks for replying. I will try to create the datatemplate in code and reply back.

0 Votes 0 · ·

The datagrid has a property (AutoGenerateColumns = true) that automatically generates the columns. So you don't have to know the structure. This works perfectly with every class structure.
Or how are the colums "structured"?

0 Votes 0 · ·

Thanks for replying!
Yes, I tried the autogenerate columns and that would work but I don't know how to then implement sorting. The only way I can see to implement the sorting is to re-query the database and I'm worried it might cause performance issues. I'm writing this for tablets that don't have a lot of processing speed.
Do you know how to sort with autogenerated columns?

0 Votes 0 · ·

In WPF works AutoGenerateColumns with CanUserSortColumns automatically without problems. But in UWP it is differente. It seems that the developer must sort the list by itself.

Do you have a lot of records? Do you use paging?

It depends how many records are shown in the datagrid.

Maybe do you have a lot of records in the database and with filters you get only a small result to show it in the datagrid.
In this case it could be a good solution to hold the result. Then sort this result without calling the database.

With paging you have call always the database.

It could be a performance issue if you don't realy know the structure of the record. Because to sort an "unknown" list you have to use reflection and this is not the best. If the result is small then it would be work, but not with 1000 records.

Of course if you show a lot of records in the datagrid, it takes a lot of time to load all records from the database.

0 Votes 0 · ·
Show more comments

1 Answer

Elmar-1103 avatar image
0 Votes"
Elmar-1103 answered ·

Set on datagrid this: AutoGenerateColumns = true. Whit this setting the datagrid creates the columns automatically in base of the object.

For sorting set this CanUserSortColumns = true.

In backend sort the list:

         private List orginalSource = new List();
         private List sortedItems = new List();
         private Dictionary itemProperties = new Dictionary();
    
         public List SortedItems
         {
             get => sortedItems; 
             set
             {
                 sortedItems = value;
                 OnPropertyChanged();
             }
         }
    
         private void InitializeList()
         {
             //Get list from the database
             SortedItems = orginalSource = GetFromDb();
    
             //initialize data structure to get the properties
             itemProperties = new Dictionary();
    
             var firstItem = sortedItems?.First();
             if (firstItem != null)
             {
                 foreach (PropertyDescriptor propertyDescriptor in TypeDescriptor.GetProperties(firstItem))
                 {
                     itemProperties[propertyDescriptor.Name] = propertyDescriptor;
                 }
             }
         }
    
         private async void DataGrid_Sorting(object sender, DataGridColumnEventArgs e)
         {
             if (e.Column.SortDirection != DataGridSortDirection.Ascending)
             {
                 e.Column.SortDirection = DataGridSortDirection.Ascending;
                 SortedItems = orginalSource.OrderBy(x => GetDynamicValue(x, e.Column.Header.ToString())).ToList();
             }
             else
             {
                 e.Column.SortDirection = DataGridSortDirection.Descending;
                 SortedItems = orginalSource.OrderByDescending(x => GetDynamicValue(x, e.Column.Header.ToString())).ToList();
             }
    
             //wait a little bit, that the datagrid can recreate all
             await Task.Delay(10);
    
             DataGrid dg = sender as DataGrid;
    
             //reset sort direction of the column
             foreach (var column in dg.Columns)
             {
                 if(column.Header == e.Column.Header)
                 {
                     column.SortDirection = e.Column.SortDirection;
                 }
             }
         }
    
         private object GetDynamicValue(dynamic item, string propertyName)
         {
             if (itemProperties.ContainsKey(propertyName))
                 return itemProperties[propertyName].GetValue(item);
             else
                 return null;
         }


· Share
10 |1000 characters needed characters left characters exceeded

Up to 10 attachments (including images) can be used with a maximum of 3.0 MiB each and 30.0 MiB total.