我有一个数据集,其元素在DataGrid中显示为行。行的排序顺序会根据外部事件而更改。
我最初的想法是将行存储为ObservableCollection并在更新后使用该集合。但是我遇到了两个问题: 1)ObservableCollection没有Sort()方法 2)如果我自己尝试对元素进行排序,每当我尝试将元素分配给新位置时都会出现异常,例如在交换函数中,例如
class MyCollection : ObservableCollection<T>
{
void swap( int i, int j )
{
T tmp = this[i];
this[i] = this[j]; // THROWS A NOT SUPPORTED EXCEPTION
this[j] = tmp;
}
}
所以问题是......如何填充行顺序需要动态更新的DataGrid?
我终于得到了一个答案,我将在下面进行描述。
答案 0 :(得分:1)
我通过显式实现INotifyCollectionChanged(而不是使用ObservableCollection)来实现这一点。此外,我发现使用Update操作导致相同的“不支持”错误,但我可以使用“添加”和“删除”操作。所以我的交换功能看起来像这样:
class MyCollection<T> : List<T>, INotifyCollectionChanged
{
public event NotifyCollectionChangedEventHandler CollectionChanged;
private void swap( int i, int j )
{
T a = this[i];
T b = this[j];
// swap my own internal data storage
this[i] = b;
this[j] = a;
// and also let my CollectionChanged listener know that I have done so.
if( CollectionChanged != null )
{
NotifyCollectionChangedEventArgs arg;
arg = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Remove, a, i );
CollectionChanged( this, arg );
arg = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, b, i );
CollectionChanged( this, arg );
arg = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Remove, b, j );
CollectionChanged( this, arg );
arg = new NotifyCollectionChangedEventArgs(
NotifyCollectionChangedAction.Add, a, j );
CollectionChanged( this, arg );
}
}
}
动态更改是相当本地的,所以幸运的是,使用较慢的手写排序来响应更改对我来说是正常的。换句话说,当更新到达时,我调用另一个看起来像这样的成员函数(在同一个集合中):
public void ProcessUpdates( List<T> updateList )
{
// use the contents of updateList to modify my internal store
// ...
// and now resort myself
sort();
}
private void sort()
{
// implement your favorite stable sorting algorithm here, calling
// swap() whenever you swap two elements.
// (this is an intentionally facetious sorting algorithm, because I
// don't want to get into the long and irrelevant details of my own
// data storage.)
while( i_am_not_sorted() )
{
int i = random_index();
int j = random_index();
if( out_of_order(i,j) )
{
// modify my internal data structure and
// also let my CollectionChanged listener know that I have done so
swap( i, j );
}
}
}
不要忘记在向集合中添加元素时也需要触发“添加”通知!我对初始列表进行排序,然后按排序顺序添加,这使我在第一次填充数据时可以使用更高效的库排序。