pelz
pelz

Reputation: 169

My C# ListView Compare Function is too slow

I am trying to sort a ListView which also has a DateTime column. This is the code I use:

public bool isDate(Object obj)
{
    string strDate = obj.ToString();
    try
    {
        DateTime dt = DateTime.Parse(strDate);
        if (dt != DateTime.MinValue && dt != DateTime.MaxValue)
            return true;
        return false;
    }
    catch
    {
        return false;
    }
}

public int Compare(object o1, object o2)
{
    if (!(o1 is ListViewItem))
        return (0);
    if (!(o2 is ListViewItem))
        return (0);

    ListViewItem lvi1 = (ListViewItem)o2;
    string str1 = lvi1.SubItems[ByColumn].Text;
    ListViewItem lvi2 = (ListViewItem)o1;
    string str2 = lvi2.SubItems[ByColumn].Text;

    int result;
    if (lvi1.ListView.Sorting == SortOrder.Ascending)
    {
        if (isDate(str1) && isDate(str2))
            result = DateTime.Compare(DateTime.Parse(str1), DateTime.Parse(str2));
        else
            result = String.Compare(str1, str2);
    }
    else
        result = String.Compare(str2, str1);

    LastSort = ByColumn;
    return result;
}

The ListView holds about 2000 entries and the problem is that it's very slow. What am I doing wrong? Any ideas?

Thanks in advance!

Edit: Thank you very much. I am new to this and here is my code now. It is much faster and I fixed my logic.

public int Compare(object o1, object o2)
{
    var lvi1 = o2 as ListViewItem;
    var lvi2 = o1 as ListViewItem;
    if (lvi1 == null || lvi2 == null)
        return 0;

    string str1 = lvi1.SubItems[ByColumn].Text;
    string str2 = lvi2.SubItems[ByColumn].Text;

    int result;
    DateTime dateValue1 = new DateTime();
    DateTime dateValue2 = new DateTime();

    if (lvi1.ListView.Sorting == SortOrder.Ascending)
    {  
        if (DateTime.TryParse(str1, out dateValue1) && DateTime.TryParse(str2, out dateValue2)) 
            result = DateTime.Compare(dateValue1, dateValue2);
        else
            result = String.Compare(str1, str2);
    }
    else
    {
        if (DateTime.TryParse(str1, out dateValue1) && DateTime.TryParse(str2, out dateValue2))
            result = DateTime.Compare(dateValue2, dateValue1);
        else
            result = String.Compare(str2, str1);
    }

    LastSort = ByColumn;
    return result;  
}

Upvotes: 1

Views: 496

Answers (2)

user826259
user826259

Reputation:

Can't you just set your ListViewItem.Tag to the DateTime? Then when comparing the DateTimes:

DateTime d = (DateTime)ListViewItem.Tag;

Upvotes: 1

Saeed Amiri
Saeed Amiri

Reputation: 22555

Some optimization comes in my mind:

  1. Instead of isDate use:DateTime.TryParse

  2. Instead of doing two time casting:

    if (!(o1 is ListViewItem)) return (0);

    ListViewItem lvi1 = (ListViewItem)o2;

use one time casting:

var lvi1 = o2 as ListViewItem;
if (lvi1 == null)
   return 0;

Also I suggest check your code logic (as I mentioned in comment).

Upvotes: 1

Related Questions