views:

1585

answers:

2

I have a custom DataGridView column that uses an embedded control that pops up a search window for the value of that column. The important thing is that the databound column is a numeric ID, but the custom column cells display a text description.

How do I get the column to sort on the text description rather than the numeric ID?

I don't see a way to override the column to sort by FormattedValue instead of Value. I could ensure that the description shows up as a separate column in my data table, but I don't see any way to say "use column VALUE_ID as DataMember but column VALUE_DESCRIPITON as 'SortMember'"

+1  A: 

What are you using as the data-source? a DataTable? The sort is most commonly provided by the list itself, so you could actually write a custom list with your own specific sort behaviour. The simplest approach (although still non-trivial) would be to inherit from BindingList<T>, and override ApplySortCore, RemoveSortCore, SupportsSortingCore, IsSortedCore, SortPropertyCore and SortDirectionCore (phew!). In particular, the ApplySortCore would have to detect the specific PropertyDescriptor, and perform the bespoke search.

I'm not saying it is trivial (quite the opposite) - but it can be done within the standard binding mechanisms.

An alternative idea might be to make the id something else, that isn't actually an int, but is a custom class/struct. It would need to implement IComparable/IComparable<T>, and have a ToString() that displays the desired text. Then you could presumably (untested) bind directly to that column.

However!!! If you aren't already familiar with System.ComponentModel, I would suggest avoiding this complexity. If the above makes sense, then fine - if not, I'm not sure I would attempt it for your first stab into that area...

Marc Gravell
Definitely not trivial! But it seems like there might not be any faster way of doing this.
Clyde
+2  A: 

You can use a technique described in the following article Column Sort Modes

private bool ascending;
private int sortColumn;
private void dgv_ColumnHeaderMouseClick(object sender, DataGridViewCellMouseEventArgs e)
{
    List<SomeObject> list = (List<SomeObject>)someBindingSource.DataSource;
    if (e.ColumnIndex != sortColumn) ascending = false;

    int 1 = e.ColumnIndex;
    if (i == DescriptionColumn.Index)
        list.Sort(new Comparison<SomeObject>((x,y) => x.ID.CompareTo(y.ID)));

    sortColumn = e.ColumnIndex;
    ascending = !ascending;
    if (!ascending) list.Reverse():

    someBindingSource.ResetBindings(false);
    // you may also have to call dgv.Invalidate();
}
Agies
A data table does not seem to be cast-able to a List<>
Clyde
Although I could just set the sort directly on the binding source at that point -- I'll have to try that.
Clyde