I have a DataGridView whose datasource is a BindingList. MyObj has a few nullable properties (like int? and DateTime?) I want to implement sorting to my binding list, so the DataGridView can sort the column when the user clicks on the column header.
After some digging around, I found and followed the answer of this question ( DataGridView Column sorting with Business Objects ).
I can't get that solution to work for Nullable types because they don't implement IComparable. Even for classes that implement IComparable like String, ApplySortCore(...) fails when the String has a null value.
Is there a solution for this? Or do I have to implement a wrapper class for "Int32?" ?
eg
public class Int32Comparable : IComparable
{
public int? Value { get; set; }
#region IComparable<int?> Members
public int CompareTo(object other)
{
// TODO: Implement logic here
return -1;
}
#endregion
}
Nullable<int>
may not implement IComparable
, but surely int
does. And Nullable<T>
always boxes to T
(for instance when you cast to an interface, such as IComparable
, which is a boxing conversion). So comparing/sorting on nullable properties should not be a problem.
int? value = 1;
IComparable comparable = value; // works; even implicitly
So, the check in the sample at the top does not work right. Try this:
Type interfaceType = prop.PropertyType.GetInterface("IComparable");
// Interface not found on the property's type. Maybe the property was nullable?
// For that to happen, it must be value type.
if (interfaceType == null && prop.PropertyType.IsValueType)
{
Type underlyingType = Nullable.GetUnderlyingType(prop.PropertyType);
// Nullable.GetUnderlyingType only returns a non-null value if the
// supplied type was indeed a nullable type.
if (underlyingType != null)
interfaceType = underlyingType.GetInterface("IComparable");
}
if (interfaceType != null)
// rest of sample
One more addition: if you want null values to work as well (both string and nullable types), you could try this re-implementation of SortCore(...)
:
protected override void ApplySortCore(PropertyDescriptor prop, ListSortDirection direction)
{
IEnumerable<MyClass> query = base.Items;
if (direction == ListSortDirection.Ascending)
query = query.OrderBy( i => prop.GetValue(i) );
else
query = query.OrderByDescending( i => prop.GetValue(i) );
int newIndex = 0;
foreach (MyClass item in query)
{
this.Items[newIndex] = item;
newIndex++;
}
this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));
}
There's no need to look for IComparable
directly, just let the sorting methods themselves sort it out.
When comparing your nullable types can you do something like this...
Int32? val1 = 30;
Int32 val2 = 50;
Int32 result = (val1 as IComparable).CompareTo(val2);
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.