2012-03-06 1 views
1

В моем окне wpf у меня есть два списка. Один - для доступных предметов, а другой - для выбранных элементов. Доступные элементы обычно будут содержать более 3000 элементов, если они не будут отфильтрованы. Пользователю предоставляется сводка для фильтрации типа элемента и текстового поля для фильтрации имени элемента. В настоящее время я использую Linq для фильтрации элементов, но он обновляет список очень медленно. Мне интересно, есть ли лучший подход.Быстрая и эффективная фильтрация списка, связанного с коллекцией в ViewModel

Интересные примечания. Я создал привязанное поведение, чтобы я мог привязать свойство selecteditems (обратите внимание на ') на модель viewmodel, поэтому для работы требуется тип коллекции. У меня есть набор текстовых фильтров для обновления свойства при изменении, а в настройщике свойств я вызываю метод фильтра.

Вид:

<DatePicker Grid.Row="0" Grid.Column="1" Height="26" VerticalAlignment="Center" SelectedDate="{Binding FromDate}" /> 
<DatePicker Grid.Row="0" Grid.Column="3" Height="26" VerticalAlignment="Center" SelectedDate="{Binding ToDate}" /> 
<ComboBox Grid.Row="1" Grid.Column="1" Height="22" VerticalAlignment="Center" ItemsSource="{Binding Classes}" SelectedItem="{Binding SelectedClass}" /> 
<TextBox Grid.Row="4" Grid.Column="1" Height="22" VerticalAlignment="Center" Text="{Binding CiNameFilterText, UpdateSourceTrigger=PropertyChanged}" Margin="55,0,0,178" /> 
<ListBox Grid.Row="4" Grid.Column="1" Height="172" ItemsSource="{Binding AvailableCis}" DisplayMemberPath="CiName" SelectionMode="Extended" Ocean_WPF:ListBoxBehavior.SelectedItems="{Binding AvailableCisSelected}" Margin="0,28,0,0" /> 
<ListBox Grid.Row="4" Grid.Column="3" Height="200" ItemsSource="{Binding SelectedCis}" DisplayMemberPath="CiName" SelectionMode="Extended" Ocean_WPF:ListBoxBehavior.SelectedItems="{Binding SelectedCisSelected}" /> 

ViewModel:

Protected Sub FilterCiList() 
    Try 
     If (_caCiData IsNot Nothing) Then 
      If ((_selectedClass IsNot Nothing AndAlso Not _selectedClass.Equals(String.Empty)) AndAlso (_ciNameFilterText IsNot Nothing AndAlso Not _ciNameFilterText.Equals(String.Empty))) Then 
       Me.AvailableCis = New ObservableCollection(Of CA.SoftwareRow)(_caCiData.Where(Function(ci) ci.Class.ToUpper.Equals(_selectedClass.ToUpper) AndAlso ci.CiName.ToUpper.Contains(_ciNameFilterText.ToUpper)).OrderBy(Function(a) a.CiName)) 
      ElseIf ((_selectedClass IsNot Nothing AndAlso Not _selectedClass.Equals(String.Empty)) AndAlso (_ciNameFilterText Is Nothing OrElse _ciNameFilterText.Equals(String.Empty))) Then 
       Me.AvailableCis = New ObservableCollection(Of CA.SoftwareRow)(_caCiData.Where(Function(ci) ci.Class.ToUpper.Equals(_selectedClass.ToUpper)).OrderBy(Function(a) a.CiName)) 
      ElseIf ((_selectedClass Is Nothing OrElse _selectedClass.Equals(String.Empty)) AndAlso (_ciNameFilterText IsNot Nothing AndAlso Not _ciNameFilterText.Equals(String.Empty))) Then 
       Me.AvailableCis = New ObservableCollection(Of CA.SoftwareRow)(_caCiData.Where(Function(ci) ci.CiName.ToUpper.Contains(_ciNameFilterText.ToUpper)).OrderBy(Function(a) a.CiName)) 
      Else 
       Me.AvailableCis = New ObservableCollection(Of CA.SoftwareRow)(_caCiData.OrderBy(Function(a) a.CiName)) 
      End If 

      If (Me.SelectedCis IsNot Nothing) Then 
       For Each Ci In Me.SelectedCis 
        Me.AvailableCis.Remove(Ci) 
       Next 
      End If 
     End If 
    Catch ex As Exception 
     _viewModelUIService.ExceptionDialog(ex) 
    End Try 
End Sub 

_caCiData является полным списком нефильтрованного. Если я фильтрую список, мне нужно отображать только элементы, соответствующие фильтру, поэтому я просто добавляю эти элементы в свойство AvailableCis, используя запрос Linq.

Там должен быть лучшим способом сделать это, как фильтрация происходит медленно (занимает около 5 секунд, прежде чем он сможет обновить список в представлении)

Edit: мой друг предложил DataView, будет что работать лучше, чем фильтровать всю коллекцию каждый раз?

ответ

0

Я понял это. Тот же друг, который предложил Dataview, просто вспомнил, что есть ошибка с WPF и загрузка его слишком большим количеством элементов. Это действительно замедлило UI. Я изменил список на Datagrids и стилизовал их, чтобы они выглядели как списки. Результат был день и ночь. У меня есть скорость, которую я хочу сейчас.

Смежные вопросы