简体   繁体   中英

DataGridView SortableBindingList for decimal numbers as strings

I'm using this SortableBindingList in my CSharp tool to sort items in DataGridView and it works fine except for decimal numbers as strings, eg "125.03"!

public class SortableBindingList<T> : BindingList<T>
{
    private ArrayList sortedList;
    private bool isSortedValue;

    public SortableBindingList()
    {
    }

    public SortableBindingList(IList<T> list)
    {
        foreach (object o in list)
        {
            this.Add((T)o);
        }
    }

    protected override bool SupportsSortingCore
    {
        get { return true; }
    }


    protected override bool IsSortedCore
    {
        get { return isSortedValue; }
    }

    ListSortDirection sortDirectionValue;
    PropertyDescriptor sortPropertyValue;

    protected override void ApplySortCore(PropertyDescriptor prop,
        ListSortDirection direction)
    {
        sortedList = new ArrayList();

        Type interfaceType = prop.PropertyType.GetInterface("IComparable");

        if (interfaceType == null && prop.PropertyType.IsValueType)
        {
            Type underlyingType = Nullable.GetUnderlyingType(prop.PropertyType);

            if (underlyingType != null)
            {
                interfaceType = underlyingType.GetInterface("IComparable");
            }
        }

        if (interfaceType != null)
        {
            sortPropertyValue = prop;
            sortDirectionValue = direction;

            IEnumerable<T> 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 (object item in query)
            {
                this.Items[newIndex] = (T)item;
                newIndex++;
            }
            isSortedValue = true;
            this.OnListChanged(new ListChangedEventArgs(ListChangedType.Reset, -1));

        }
        else
        {
            throw new NotSupportedException("Cannot sort by " + prop.Name +
                ". This" + prop.PropertyType.ToString() +
                " does not implement IComparable");
        }
    }

    protected override PropertyDescriptor SortPropertyCore
    {
        get { return sortPropertyValue; }
    }

    protected override ListSortDirection SortDirectionCore
    {
        get { return sortDirectionValue; }
    }

}

Link: DataGridView Using SortableBindingList

Which adaptions are necessary?

Thx for any help!

Possible solution:

decimal value;
if (direction == ListSortDirection.Ascending)
{
    // check if element count is not 0 and value is decimal
    if (query.Count() > 0 &&
        decimal.TryParse(prop.GetValue(query.ElementAt<T>(0)).ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out value))
    {
        // convert to decimal and sort
        query = query.OrderBy(i => Convert.ToDecimal(prop.GetValue(i)));
    }
    else query = query.OrderBy(i => prop.GetValue(i));
}
else
{
    if (query.Count() > 0 &&
        decimal.TryParse(prop.GetValue(query.ElementAt<T>(0)).ToString(), NumberStyles.Any, CultureInfo.InvariantCulture, out value))
    {
        query = query.OrderByDescending(i => Convert.ToDecimal(prop.GetValue(i)));
    }
    else query = query.OrderByDescending(i => prop.GetValue(i));
}

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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM