2008-10-24 3 views
1

У меня есть набор данных, элементы которого отображаются в виде строк в DataGrid. Порядок сортировки строк изменяется в ответ на внешние события.В Silverlight, как заполнить отсортированный 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

Я получил это для работы, явно используя INotifyCollectionChanged (вместо использования ObservableCollection). Кроме того, я обнаружил, что использование действия «Обновление» привело к той же «не поддерживаемой» ошибке, но я мог использовать действия «Добавить и удалить». Таким образом, моя функция замены заканчивает тем, как это:

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

Не забывайте, что это также необходимо уволить уведомление «Добавить» при добавлении элементов к коллекции! Я сортирую исходный список, а затем добавляю отсортированный порядок, который позволяет мне использовать более эффективную сортировку библиотеки, когда я сначала заполняю данные.