尝试手动排序PagedCollectionView时出现异常

时间:2011-07-31 18:11:55

标签: silverlight

好的我觉得我在这里做错了。

我正在使用映射到自定义类型的 ObservableCollection PagedCollectionView 。我希望能够在用户尝试对DataGrid列进行排序时手动对基础集合进行排序。

我做了以下事情:

    obs = new ObservableCollection<Seats>(arrSeats);
    view = new PagedCollectionView(obs);

    INotifyCollectionChanged sortchangeNotifier = view.SortDescriptions as INotifyCollectionChanged;
    sortchangeNotifier.CollectionChanged += new NotifyCollectionChangedEventHandler(sortchangeNotifier_CollectionChanged);
    grdData.ItemsSource = view;

    void sortchangeNotifier_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
    {
        // What to do here?
    }

只要单击列标题,就会正确调用事件处理程序。但是,每当我尝试修改ObservableCollection时,我都会遇到以下异常:

在推迟刷新时,无法更改或检查PagedCollectionView的内容或当前位置。

我希望能够实现自己的自定义排序算法。有什么想法吗?

谢谢!

修改

嗯,这特别疯狂,但是当我在事件处理程序方法中使用try / catch块包装我的代码时,实际应用了更改。任何想法:)?

2 个答案:

答案 0 :(得分:1)

您真正想要解决的问题是自定义排序PagedCollectionView -

“我正在使用映射到自定义类型的ObservableCollection的PagedCollectionView。我希望能够在用户尝试对DataGrid列进行排序时手动对基础集合进行排序。”

自定义/扩展PagedCollectionView是实现此目的的方法。当我需要做同样的事情时,我创建了一个IComparer字典

public Dictionary<string, IComparer<object>> CustomSortFunctions
    {
        get
        {
            if (this.customSortFunctions == null)
            {
                this.customSortFunctions = new Dictionary<string, IComparer<object>>();
            }
            return this.customSortFunctions;
        }
    }

这样每对的键都与DataGridColumn.SortMemberPath对应。对于您希望自定义排序的任何列,您可以添加合适的值对。

要利用此字典,请修改PagedCollectionView的SortList方法,以检查要排序的自定义比较器(然后按适用的方向排序)。例如:

if (this.CustomSortFunctions.ContainsKey(description.PropertyName))
{
    source = source.OrderBy(a => a, this.CustomSortFunctions[description.PropertyName]);
}

当用户使用数据网格“排序”时,您将进行所需的排序。

您的出发点是PagedCollectionView - 其源代码包含在Silveright Toolkit的整体源代码中(在Toolkit / Systems.Windows.Data / PagedCollection中)。

答案 1 :(得分:0)

对于任何通知更改,CollectionView和ObservableCollection齐头并进。因此,对两者中的任何一个同时对其更改通知所做的任何更改都会导致异常。

我们必须采取不同的方法。

  1. 对于WPF - 使用DataGrid.Sorting事件调用并在其事件处理程序中执行e.Handled = true。这会停止datagrid的本机排序。在e.Handled = true之前,根据需要进行自定义排序。

  2. 对于Silverlight - 使用Dispatcher.BeginInvoke()并在那里进行自定义排序任务。使用后台调度程序优先级。

  3. 如果这些有帮助,请告诉我。