We did some investigating about PropertySortDescriptor, it seems that we need target 'sort column' be a part of our grid columns, we tried it in Telerik sample project and it will give no response without the target 'sort column'. So we would like to know that we have to have a column for target property to use it as a property sort descriptor, right?
please check more details in this document: .NET MAUI DataGrid Documentation - Sorting - Telerik UI for .NET MAUI
The difference between the DelegateSortDescriptor
and the PropertySortDescriptor
is that the DelegateSortDescriptor
sorts data by a custom key, while the PropertySortDescriptor
sorts by a defined key, which is a property from the model.
2 Answers, 1 is accepted
Hi Didi. Let me add a bit more information with a sample app here. Attached.
I'll repeat the code here since it's pretty simple:
public class OuterClass
{
public InnerClass InnerObject { get; set; }
public int InnerSortProp => InnerObject.SortProp;
public int OuterSortProp { get; set; }
}
public class InnerClass
{
public int SortProp { get; set; }
}
<dataGrid:RadDataGrid ItemsSource="{Binding ItemsSource, Source={x:Reference This}}"
AutoGenerateColumns="False">
<dataGrid:RadDataGrid.Columns>
<!--<dataGrid:DataGridNumericalColumn HeaderText="Regular Numeric Column"
PropertyName="InnerObject.SortProp"/>-->
<dataGrid:DataGridTemplateColumn HeaderText="Sortable">
<dataGrid:DataGridTemplateColumn.CellContentTemplate>
<DataTemplate>
<Label x:DataType="telerikScratch:OuterClass"
Text="{Binding InnerObject.SortProp}" />
</DataTemplate>
</dataGrid:DataGridTemplateColumn.CellContentTemplate>
<dataGrid:DataGridTemplateColumn.SortDescriptor>
<dataGrid:PropertySortDescriptor PropertyName="InnerSortProp"/>
</dataGrid:DataGridTemplateColumn.SortDescriptor>
</dataGrid:DataGridTemplateColumn>
<dataGrid:DataGridTemplateColumn HeaderText="Not Sortable">
<dataGrid:DataGridTemplateColumn.CellContentTemplate>
<DataTemplate>
<Label x:DataType="telerikScratch:OuterClass"
Text="{Binding InnerObject.SortProp}" />
</DataTemplate>
</dataGrid:DataGridTemplateColumn.CellContentTemplate>
<dataGrid:DataGridTemplateColumn.SortDescriptor>
<dataGrid:PropertySortDescriptor PropertyName="InnerObject.SortProp"/>
</dataGrid:DataGridTemplateColumn.SortDescriptor>
</dataGrid:DataGridTemplateColumn>
</dataGrid:RadDataGrid.Columns>
</dataGrid:RadDataGrid>
So notice above that both uncommented columns are template columns that show InnerObject.SortProp. But one has a sort descriptor that points to a getter property that accesses InnerObject.SortProp, while another references InnerObject.SortProp directly. Ignore OuterSortProp for now, I didn't end up using it for this sample.
If you run the app as is, you'll notice that you can sort the first column without issue. But if you try to sort the 2nd column, the grid goes white and shows a busy indicator indefinitely.
But... if you then uncomment the numerical column that's bound directly to InnerObject.SortProp, then you can sort that same column without issue.
So the issue seems to be, you can't set a nested property as a sort descriptor, unless you also happen to have another column that's already bound to that nested property (Note the column doesn't need to be visible. If you set the numerical column's IsVisible=False, then the last column is still sortable). Or, you have to add an accessor property at the root object, since the properties directly on the bound object don't have this limitation.
Hope this cleared up the confusion.
Hi Teddy,
Thank you for the additional details. It was of great help for better understanding the setup you have. You are actually using a template column, not text column and applying sort descriptor to a template column.
I have tested the case and reproduced the behavior. The reason for this behavior is missing NestedPropertySortDescriptor for template column.
For example this works:
<dataGrid:DataGridTemplateColumn.SortDescriptor>
<dataGrid:PropertySortDescriptor PropertyName="InnerSortProp"/>
</dataGrid:DataGridTemplateColumn.SortDescriptor>
as the property is a property from the model,
and this doesn't:
<dataGrid:DataGridTemplateColumn.SortDescriptor>
<dataGrid:PropertySortDescriptor PropertyName="InnerObject.SortProp"/>
</dataGrid:DataGridTemplateColumn.SortDescriptor>
as the property is a nested property.
I have logged this here: https://feedback.telerik.com/maui/1601695-datagrid-provide-a-nested-property-sort-descriptor-for-templatecolumn - cast your vote for the item and press the follow button to track its progress.
When uncomment the numerical column/text column/other built-in column, the sorting applies as expected. As this sort descriptor is applied to the entire DataGrid.
Let me know if you have any further questions on this.
Hello Scofield,
The DataGrid Sorting is applied per column. The property used in the property sort descriptor is a property from the model.
For example you have the following business model:
public class Data
{
public string Country { get; set; }
public string Capital { get; set; }
}
and if you want to sort the grid by country column, the grid definition is as follow:
<telerik:RadDataGrid x:Name="dataGrid" AutomationId="dataGrid">
<telerik:RadDataGrid.Columns>
<telerik:DataGridTextColumn PropertyName="Country"/>
<telerik:DataGridTextColumn PropertyName="Capital"/>
</telerik:RadDataGrid.Columns>
<telerik:RadDataGrid.SortDescriptors>
<telerik:PropertySortDescriptor PropertyName="Country"/>
</telerik:RadDataGrid.SortDescriptors>
</telerik:RadDataGrid>
If there is something unclear how the property sort descriptors works, please let me know. If you want to achieve custom sorting, then you have to use the delegate sort descriptor.
Programmatic sorting example can be found in the SDK Browse MAUI application: https://github.com/telerik/maui-samples/tree/main/Samples/SdkBrowser/Examples/DataGridControl/SortingCategory/ProgrammaticSortingExample
Regards,
Didi
Progress Telerik
Love the Telerik and Kendo UI products and believe more people should try them? Invite a fellow developer to become a Progress customer and each of you can get a $50 Amazon gift voucher.
our case is more like: have 3 fields binging into the grid, we make C3 column visibility = false and make C1 column sort by C3 value. and we found out we have to create a column for C3 and make visibility = false, I known DelegateSortDescriptor
can make it happen as well, but I just wanted to confirm we have to have a column for target property to use it as a property sort descriptor
<telerik:RadDataGrid x:Name="dataGrid" AutomationId="dataGrid">
<telerik:RadDataGrid.Columns>
<telerik:DataGridTextColumn PropertyName="C1"/>
<telerik:DataGridTextColumn PropertyName="C2"/>
<telerik:DataGridTextColumn PropertyName="C3"/>
</telerik:RadDataGrid.Columns>
</telerik:RadDataGrid>
Hi Scofield,
I am not sure I understood the behavior. For example this is my setup:
I have 2 columns, and sort by another property in the model:
<Grid>
<telerik:RadDataGrid x:Name="grid"
AutoGenerateColumns="False">
<telerik:RadDataGrid.BindingContext>
<local:ViewModel />
</telerik:RadDataGrid.BindingContext>
<telerik:RadDataGrid.Columns>
<telerik:DataGridTextColumn PropertyName="Name"
HeaderText="Name"/>
<telerik:DataGridTextColumn PropertyName="Country"/>
</telerik:RadDataGrid.Columns>
<telerik:RadDataGrid.SortDescriptors>
<telerik:PropertySortDescriptor PropertyName="Capital"/>
</telerik:RadDataGrid.SortDescriptors>
</telerik:RadDataGrid>
</Grid>
and the sample data for the test:
this.grid.ItemsSource = new List<Data>
{
new Data { Country = "India", Capital = "New Delhi", Name = "Hello"},
new Data { Country = "South Africa", Capital = "Cape Town", Name="ABC"},
new Data { Country = "Nigeria", Capital = "Abuja", Name = "My Name" },
new Data { Country = "Singapore", Capital = "Singapore", Name = "GGGGG"}
};
The grid is sorted as expected.
If I have the following setup:
<telerik:RadDataGrid x:Name="grid"
AutoGenerateColumns="False">
<telerik:RadDataGrid.BindingContext>
<local:ViewModel />
</telerik:RadDataGrid.BindingContext>
<telerik:RadDataGrid.Columns>
<telerik:DataGridTextColumn PropertyName="Name"
HeaderText="Name"/>
<telerik:DataGridTextColumn PropertyName="Country"/>
<telerik:DataGridTextColumn PropertyName="Capital" IsVisible="False"/>
</telerik:RadDataGrid.Columns>
<telerik:RadDataGrid.SortDescriptors>
<telerik:PropertySortDescriptor PropertyName="Capital"/>
</telerik:RadDataGrid.SortDescriptors>
</telerik:RadDataGrid>
The grid is also sorted as expected. For the first test, I do not have a column for Capital property but the grid sorts by Capital.
The property sort descriptor is used to sort by a property name. I am not sure how you sort the C1 column by C3 property using property sort descriptor. I do not see a sort descriptor in the xaml you have shared. Please send me the complete setup, so I can review the code.