2016-10-31 2 views
0

У меня есть метод, который запрашивает базу данных с использованием структуры сущностей и помещает результаты в ICollectionView. ICollectionView действует как ItemsSource для DataGrid. Все работает нормально в первом запросе, но после второго запроса данные сортируются неправильно, несмотря на применение правильного SortDescriptions.ICollectionView Sort не работает после смены источника

Вот мой код пытается запрашивание и группировка/сортировка данных:

CollectionViewSource cvsRS; 

    private ObservableCollection<productorder> rs; 
    public ObservableCollection<productorder> RS 
    { 
     get { return rs; } 
     set 
     { 
      if (rs != value) 
      { 
       rs = value; 
       OnPropertyChanged("RS"); 
      } 
     } 
    } 

    private ICollectionView rsView; 
    public ICollectionView RSView 
    { 
     get { return rsView; } 
     set 
     { 
      if (rsView != value) 
      { 
       rsView = value; 
       OnPropertyChanged("RSView"); 
      } 
     } 
    } 

    public void QueryDatabase() 
    { 

     RS = new ObservableCollection<productorder>(DatabaseEntities.productorders.Where(o => o.month.id == CurrentMonth.id)); 
     if (RS != null) 
     { 
      cvsRS.Source = RS; 
      RSView = cvsRS.View; 

      RSView.GroupDescriptions.Clear(); 
      RSView.GroupDescriptions.Add(new PropertyGroupDescription("producttype.productcategory.name")); 
      RSView.GroupDescriptions.Add(new PropertyGroupDescription("producttype.name")); 

      RSView.SortDescriptions.Clear(); 
      RSView.SortDescriptions.Add(new SortDescription("producttype.productcategory.sortorder", ListSortDirection.Ascending)); 
      RSView.SortDescriptions.Add(new SortDescription("client.name", ListSortDirection.Ascending)); 
      RSView.Refresh(); 
      CurrentRecord = null; 
      SelectedRecords = null; 
     } 
    } 

Группировка работает отлично, но группы не в правильном порядке, основанном на сортировке. Я пробовал ряд возможных «исправлений» без каких-либо успехов (например, добавляя описания сортировки/группы непосредственно к CollectionViewSource, сортируя перед группировкой, удаляя часть сортировки/группировки, удаляя SortDescriptions за CollectionViewSource does not re-sort on property change).

Кто-нибудь знает, как поддерживать порядок сортировки независимо от того, сколько запросов выполняется? Я открыт для альтернативных методов запроса отображения данных в DataGrid, если это может сработать.

+0

Я попытался привязать источник (не назначать, связывать, используя экземпляр класса «Binding») один раз, в свойство «ObservableCollection », которое вызывает «PropertyChanged», когда вы даете ему новую коллекцию. Затем заселите, изменив свойство. Либо бросьте в новую коллекцию, либо очистите и заселите старый. Но никогда не прикасайтесь к 'cvsRS.Source', за исключением того, чтобы сначала настроить Binding. –

+0

Надеюсь, я правильно это интерпретировал, я сделал это в своем конструкторе: 'cvsRS = new CollectionViewSource(); cvsRS.Source = новое привязка («RS»); RSView = cvsRS.View; ' Но я получаю сообщение об ошибке:« System.Windows.Data.Binding »не является допустимым значением для свойства« Источник ». –

+0

Я быстро взвесил тест, и он работал так, как я ожидал, поэтому я опубликовал ответ с примером того, как сделать привязку. Вставка этого комментария в любом случае будет нечитабельной. –

ответ

1

Попробуйте привязать свой CollectionViewSource.Source к вашему ObservableCollection<T>. Настройте привязку в конструкторе viewmodel. Тогда просто оставьте это в покое. Обновите ObservableCollection<T>, замените его и т. Д. Пока это ObservableCollection<T>, и его общественное имущество поднимает PropertyChanged всякий раз, когда вы его заменяете, все будет работать.

public MyViewModel() 
{ 
    BindCollectionViewSource(); 
} 

protected void BindCollectionViewSource() 
{ 
    cvsRS = new CollectionViewSource(); 

    var binding = new Binding 
    { 
     Source = this, 
     Path = new PropertyPath("RS") 
    }; 
    BindingOperations.SetBinding(cvsRS, CollectionViewSource.SourceProperty, binding); 
} 

// Since we're not going to be messing with cvsRS or cvsRS.View after the 
// constructor finishes, RSView can just be a plain getter. The value it returns 
// will never change. 
public ICollectionView RSView 
{ 
    get { return cvsRS.View; } 
} 

Вы не можете просто назначить привязку к Source; есть нечто большее, чем это. Файл Source="{Binding RSView}", который вы видите в XAML, может выглядеть как задание, но некоторые детали скрываются для удобства. Binding активно делает материал. Он должен знать, кем является целевой объект.

Я видел одну забавную вещь: я дал свой тестовый код один PropertyGroupDescription и один SortDescription. Когда я добавлял элементы в коллекцию, они сортировали их внутри групп. Затем, когда я вызвал RSView.Refresh(), он применил их без ссылки на группы. Не уверен, что я понял, что он там делает.

+0

Спасибо Ed. Я реализовал код выше, но мой DataGrid никогда не показывает никаких данных. Его 'ItemsSource' привязан к' RSView'. Я также сохранял метод 'QueryDatabase' идентичным, за исключением удаления' cvsRS.Source = RS; RSView = cvsRS.View; ' –

+0

Просто попробуйте RS.Clear() и добавьте в него элементы вместо создания новой коллекции. –

+0

Это сработало. Благодаря! –