在Silverlight中,如何从动态变化的连接填充已排序的DataGrid

时间:2008-10-24 17:09:44

标签: silverlight sorting datagrid

我有一个数据集,其元素在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?

我终于得到了一个答案,我将在下面进行描述。

1 个答案:

答案 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 );
       }
    }
}

不要忘记在向集合中添加元素时也需要触发“添加”通知!我对初始列表进行排序,然后按排序顺序添加,这使我在第一次填充数据时可以使用更高效的库排序。