В моем окне wpf у меня есть два списка.Один для доступных предметов, а другой для выбранных предметов.Доступные предметы обычно содержат 3000+ предметов, если не отфильтрованы.Пользователю предоставляется поле со списком для фильтрации по типу элемента и текстовое поле для фильтрации по имени элемента.В настоящее время я использую Linq для фильтрации элементов, но список обновляется очень медленно.Мне интересно, есть ли лучший подход.
Некоторые примечания, представляющие интерес: я создал прикрепленное поведение, чтобы позволить мне привязывать свойство selecteditems (обратите внимание на 's') к модели представления и этому поведениютребуется тип коллекции для работы.У меня установлен текстовый фильтр для обновления свойства при его изменении, и в установщике свойств я вызываю метод фильтра.
Просмотр:
<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 секунд, прежде чем он сможет обновить список в представлении)
Редактировать: мой друг предложил просмотр данных, будет ли это работать лучше, чем фильтровать всю коллекцию каждый раз?