为 ListView 订购 ObservableCollection

Order ObservableCollection for ListView

我在为 ListView 排序数据时遇到问题。我有 EventDisplay class,它是 ListView 的 ObservableCollection(称为事件)

private ObservableCollection<EventDisplay> currentEvents = new ObservableCollection<EventDisplay>();

private void Events_Loaded(object sender, RoutedEventArgs e)
{
    sv = (ScrollViewer)VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this.Events, 0), 0);

    Events.ItemsSource = currentEvents;            
}

然后我按功能添加新数据:

private void LoadDataToList(List<EventDisplay> newItems)
{
        foreach (EventDisplay ed in newItems)
        { 
            //Set some additional data
            currentEvents.Add(ed);
        }   
        //When this line below is commented ListView data is updated
        //but is not sorted, when i uncomment the listview data is not being updated

        //currentEvents = new ObservableCollection<EventDisplay>(currentEvents.OrderByDescending(x => x.ed.date).ToList());                   
    }

那么在 Windows 8.1 应用程序中为 ListView 排序数据的正确方法是什么?

您应该执行以下操作:

currentEvents = new ObservableCollection<EventDisplay>(currentEvents.OrderByDescending(x => x.ed.date).ToList()); 
Events.ItemsSource = currentEvents;

这会强制 ListView 重新绑定到新的已排序可观察集合。

另一种选择是就地对 Observable 集合进行排序。但是,它可能会引起闪烁,因为 ListView 会随着排序的进行不断更新。

如果不想让ScrollView重置位置,可以保存scrollview的位置,等列表排序后再恢复。 我成功实现了支持排序的自定义 ObservableCollection,但通过在排序期间暂停更改通知然后发出重置通知来防止 UI 闪烁。即使遇到重置事件,ScrollView 也应保持在当前位置。

将此用于您的添加项目代码:

    foreach (EventDisplay ed in newItems.OrderByDescending(x => x.ed.date).ToList()
    { 
        //Set some additional data
        currentEvents.Add(ed);
    }  

你不起作用的原因是你被重新分配了 currentEvents 引用而不是更新 ObservableCollection

您可以对 ObservableCollection 的视图进行排序和过滤(解释 here

public class ViewableCollection<T> : ObservableCollection<T>
    {
        private ListCollectionView _View;
        public ListCollectionView View
        {
            get
            {
                if (_View == null)
                {
                    _View = new ListCollectionView(this);
                }
                return _View;
            }
        }
    }

示例的数据结构:

interface ICustomer
{
   string CuctomerName{get;set;}
   int Age{get;set;}
}

代码使用示例:

ViewableCollection<ICustomer> vCustomers = new ViewableCollection<ICustomer>();
// Sorting settings:
ViewableCollection<ICustomer> vCustomers.View.SortDescriptions.Add(new SortDescription("CustomerName", ListSortDirection.Ascending));
vCustomers.View.Filter = MyCustomFilterMethod;
// add data to collection
MyCustomers.ToList().ForEach(customer => vCustomers.Add(customer));

过滤方法示例:

private bool MyCustomFilterMethod(object item)
{
    ICustomer customer = item as ICustomer;
    return customer.Age > 25;
}

当您需要刷新过滤器时,您唯一需要做的就是调用:

this.vCustomers.View.Refresh();

然后将 GUI 绑定到 vCustomers.View 您不需要重置绑定源等。