Skip to content

allow sorting based on separate attribute - #239

Open
eneville-cd wants to merge 1 commit into
akgulebubekir:mainfrom
eneville-cd:main
Open

allow sorting based on separate attribute#239
eneville-cd wants to merge 1 commit into
akgulebubekir:mainfrom
eneville-cd:main

Conversation

@eneville-cd

Copy link
Copy Markdown

Allow binding on the row object, but set sort based on a specific attribute, for use in control templates

@symbiogenesis

Copy link
Copy Markdown
Collaborator

Hi, sorry for the lack of response.

Could you explain more about what the purpose of this is? Maybe provide an example of how and why one would want this?

Seems like the kind of thing that you could work around using logic in your ViewModel, and may not be worth expanding the API of the datagrid for.

@symbiogenesis

symbiogenesis commented Jul 11, 2026

Copy link
Copy Markdown
Collaborator

For instance, if you have a complex object in the column, and you want to sort on that complex object, then inheriting that object from IComparable and implementing the comparison in the object is actually the cleanest approach.

No need to modify the ViewModel, even.

@eneville-cd

eneville-cd commented Jul 11, 2026

Copy link
Copy Markdown
Author

For instance, if you have a complex object in the column, and you want to sort on that complex object, then inheriting that object from IComparable and implementing the comparison in the object is actually the cleanest approach.

No need to modify the ViewModel, even.

That might very well be. My issue was that I needed the whole object to present my content template appropriately (bold vs not bold based on read status), so I bind to ".", but I still want to make sure the column itself sorts by the appropriate property in the underlying object.

If there's a more elegant way of doing something like that, I'm certainly open to it. My applicable view code is as follows, if you're curious.

<dataGrid:DataGridColumn SortingEnabled="True" Title="{Binding Source={x:Static helpers:LocalizationHelper.Instance}, Path=[BroadcastMessagePopup_Header1]}" PropertyName="." SortPropertyName="SentDateTimeClean" Width="180" > <dataGrid:DataGridColumn.CellTemplate> <DataTemplate x:DataType="models:BroadcastMessageEntry"> <ContentView> <Label Text="{Binding SentDateTimeClean}" FontSize="{Binding FontSize, FallbackValue='14'}" Margin="2"> <Label.Triggers> <DataTrigger TargetType="Label" Binding="{Binding IsRead}" Value="False"> <Setter Property="FontAttributes" Value="Bold"/> </DataTrigger> </Label.Triggers> <Label.GestureRecognizers> <TapGestureRecognizer Command="{Binding BindingContext.BroadcastMessageClickedCommand, Source={RelativeSource Mode=FindAncestor, AncestorType={x:Type view:BroadcastMessagePopup}}}" CommandParameter="{Binding .}" /> </Label.GestureRecognizers> </Label> </ContentView> </DataTemplate> </dataGrid:DataGridColumn.CellTemplate> </dataGrid:DataGridColumn>

@symbiogenesis

Copy link
Copy Markdown
Collaborator

You would just leave off the SortPropertyName and make BroadcastMessageEntry inherit from IComparable

public class BroadcastMessageEntry : IComparable<BroadcastMessageEntry>, IComparable
{
    public DateTime SentDateTimeClean { get; set; }

    public int CompareTo(BroadcastMessageEntry? other)
    {
        if (other is null)
        {
            return 1;
        }

        return SentDateTimeClean.CompareTo(other.SentDateTimeClean);
    }

    public int CompareTo(object? obj)
    {
        if (obj is null)
        {
            return 1;
        }

        if (obj is not BroadcastMessageEntry other)
        {
            throw new ArgumentException($"Object must be of type {nameof(BroadcastMessageEntry)}.", nameof(obj));
        }

        return CompareTo(other);
    }
}

@symbiogenesis
symbiogenesis self-requested a review July 12, 2026 16:42
@eneville-cd

eneville-cd commented Jul 12, 2026 via email

Copy link
Copy Markdown
Author

@symbiogenesis

Copy link
Copy Markdown
Collaborator

IComparable allows you to treat a C# class as if it were sortable like a number. LINQ methods like OrderBy operate on IComparable which is implemented by number types and can also be implemented by classes. My code above provides the ability to sort on the nested DateTime property that you showed in your snippet.

@eneville-cd

eneville-cd commented Jul 13, 2026 via email

Copy link
Copy Markdown
Author

@symbiogenesis

Copy link
Copy Markdown
Collaborator

Just inherit the BroadcastMessageEntry class from IComparable, as I showed.

Then, the DataGrid will magically sort on the same property you were targeting, which is SentDateTimeClean.

The logic in the method overrides can be modified to change how sorting works.

IComparable is infinitely flexible because the sorting can be any algorithm that you think of, but in this case it is just sorting on a DateTime in a normal way.

@eneville-cd

eneville-cd commented Jul 14, 2026 via email

Copy link
Copy Markdown
Author

@symbiogenesis

Copy link
Copy Markdown
Collaborator

Ok, I see now that you want multiple columns based on one nested object.

In that case I would recommend assigning the ItemsSource to a custom DTO (or custom nested ViewModel)

Projecting to a new class is correct in this case and provides better encapsulation and potentially better efficiency.

IComparable is more like if you wanted a complex object to be sortable based on custom sorting logic. Sorting based on a name property or date property, for example.

But to project multiple nested properties up a level to work as columns, you should use a DTO (or ViewModel)

Just define a class with all the columns you are looking for, and make sure that class is filled with the appropriate data.

@eneville-cd

eneville-cd commented Jul 14, 2026 via email

Copy link
Copy Markdown
Author

@symbiogenesis

symbiogenesis commented Jul 14, 2026

Copy link
Copy Markdown
Collaborator

Ok, I think I have a handle on this, now.

Sorting on multiple non-nested properties: works

Sorting on multiple nested properties via the dot syntax: works

Sorting on a single complex custom column type without the dot syntax: works via IComparable

Sorting on multiple complex custom columns of the same type without the dot syntax: not possible in this library

My reflexive opposition was based on the idea that if you are doing something like this, that you probably just should've flattened your data structure or something.

However, you are using other properties within the template to dynamically alter the way each column is displayed.

I can see now why you want the new BindableProperty, although it is a very specialized use-case.

Looks like other data grids do support this. Sometimes they call it DataGridColumn.SortMemberPath

@symbiogenesis symbiogenesis reopened this Jul 14, 2026
@symbiogenesis

Copy link
Copy Markdown
Collaborator

@copilot resolve the merge conflicts in this pull request

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants