【问题标题】:Sorting ObservableCollection<> manually手动排序 ObservableCollection<>
【发布时间】:2012-06-25 14:18:27
【问题描述】:

我在课堂上关注ObservableCollection,我在Windows phone 7 应用程序中使用该集合将数据绑定到我的listbox

public ObservableCollection<CustomClass> myList = new ObservableCollection<CustomClass>();

我的自定义类

public class CustomClass
{
public string Id { get; set; }        
public string Name { get; set; }        
public string EventName { get; set; }        
public string EventDate get
{
    return EventDate;
}
set
{
    if (value != null)
    {
        DateTime eventDate = DateTime.Parse(value);
        int today = DateTime.Now.Day;
        if (eventDate.Day <= today + 1 & eventDate.Day >= today - 2)
        {
            if (eventDate.Day == today)
            EventDate = "Today";
            else if (eventDate.Day == (today + 1))
            EventDate = "Tomorrow";
            else if (eventDate.Day == (today - 1))
            EventDate = "Yesterday";
            else if (eventDate.Day >= (today - 2))
            EventDate = "Just Passed";
        }
        else
        {
            EventDate = value;
        }
    }
}
}

现在我想根据EventDate中的数据对myList进行排序

EventDate 中的数据在所有情况下都是以下之一

  1. 刚刚过去
  2. 昨天
  3. 明天
  4. 今天
  5. 日期 //格式“MMM/dd”

自定义集合只能按照上面的顺序排序

我从不同来源获取数据,因此在将数据绑定到集合时无法进行排序

有可能吗?

【问题讨论】:

  • 是的,我只想使用EventDate 进行排序,但我正在根据日期更改EventDate 中的数据

标签: c# .net windows-phone-7 windows-phone-7.1 observablecollection


【解决方案1】:

由于您的 CustomClass 没有实现 INotifyPropertyChange,我假设您只需在插入时进行排序(添加到集合时)。所以恕我直言,最简单的事情(类似于 Randolf Rincón-Fadul 的解决方案)是子类化,然后重写 Add 方法。

public class ComparingObservableCollection<T> : ObservableCollection<T>
     where T : IComparable<T>
{

    protected override void InsertItem(int index, T item)
    {
        int i = 0;
        bool found = false;
        for (i = 0; i < Items.Count; i++)
        {
            if (item.CompareTo(Items[i]) < 0) {
                found = true;
                break;
            }
        }

        if (!found) i = Count;

        base.InsertItem(i, item);
    }
}

那么你所要做的就是像这样在 CustomClass 上实现IComparable&lt;CustomClass&gt;

public class CustomClass : IComparable<CustomClass>
{
public string Id { get; set; }        
public string Name { get; set; }        
public string EventName { get; set; }        
public string EventDate { get
{
    return EventDate;
}
set
{
    if (value != null)
    {
        DateTime eventDate = DateTime.Parse(value);
        int today = DateTime.Now.Day;
        if (eventDate.Day <= today + 1 & eventDate.Day >= today - 2)
        {
            if (eventDate.Day == today)
            EventDate = "Today";
            else if (eventDate.Day == (today + 1))
            EventDate = "Tomorrow";
            else if (eventDate.Day == (today - 1))
            EventDate = "Yesterday";
            else if (eventDate.Day >= (today - 2))
            EventDate = "Just Passed";
        }
        else
        {
            EventDate = value;
        }
    }
}
    private int Order { get {
       switch(EventDate) {
         case "Just Passed": return 1;
         case "Yesterday": return 2;
         case "Tomorrow": return 3;
         case "Today": return 4;
         default: return 5;
       }
    }
    }

    public int CompareTo(CustomClass other) {
       return this.Order.CompareTo(other.Order);
    }
}

【讨论】:

    【解决方案2】:

    【讨论】:

      【解决方案3】:

      你总是可以子类化:

      /// <summary>
      /// Represents a dynamic data collection that provides notifications when items get added, removed, or when the whole list is refreshed and allows sorting.
      /// </summary>
      /// <typeparam name="T">The type of elements in the collection.</typeparam>
      public class SortableObservableCollection<T> : ObservableCollection<T>
      {
          /// <summary>
          /// Sorts the items of the collection in ascending order according to a key.
          /// </summary>
          /// <typeparam name="TKey">The type of the key returned by <paramref name="keySelector"/>.</typeparam>
          /// <param name="keySelector">A function to extract a key from an item.</param>
          public void Sort<TKey>(Func<T, TKey> keySelector)
          {
              InternalSort(Items.OrderBy(keySelector));
          }
      
          /// <summary>
          /// Sorts the items of the collection in ascending order according to a key.
          /// </summary>
          /// <typeparam name="TKey">The type of the key returned by <paramref name="keySelector"/>.</typeparam>
          /// <param name="keySelector">A function to extract a key from an item.</param>
          /// <param name="comparer">An <see cref="IComparer{T}"/> to compare keys.</param>
          public void Sort<TKey>(Func<T, TKey> keySelector, IComparer<TKey> comparer)
          {
              InternalSort(Items.OrderBy(keySelector, comparer));
          }
      
          /// <summary>
          /// Moves the items of the collection so that their orders are the same as those of the items provided.
          /// </summary>
          /// <param name="sortedItems">An <see cref="IEnumerable{T}"/> to provide item orders.</param>
          private void InternalSort(IEnumerable<T> sortedItems)
          {
              var sortedItemsList = sortedItems.ToList();
      
              foreach (var item in sortedItemsList)
              {
                  Move(IndexOf(item), sortedItemsList.IndexOf(item));
              }
          }
      }
      

      然后使用 lambda 表达式进行排序

      ((SortableObservableCollection<CustomClass>)MyList).Sort(s => s.EventDate);
      

      【讨论】:

      • 这可以按我在问题中提到的顺序进行排序吗??
      • 有一些静态数据将根据日期替换EventDate
      • @RaghuveerGuthikonda 在任何情况下,从属性访问器返回的值都是 Date 类型,因此它必须工作。
      • 当前上下文中不存在名称“Move”
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-03-23
      • 2011-08-13
      • 1970-01-01
      • 2017-11-02
      • 2016-10-22
      • 1970-01-01
      相关资源
      最近更新 更多