【发布时间】:2012-03-24 01:17:15
【问题描述】:
在我的 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}" />
视图模型:
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 是完整的未过滤列表。如果我过滤列表,我只需要显示与过滤器匹配的项目,因此我只需使用 Linq 查询将这些项目添加到 AvailableCis 属性。
必须有更好的方法来做到这一点,因为过滤很慢(大约需要 5 秒才能刷新视图中的列表)
编辑:我的一个朋友建议使用数据视图,这会比每次过滤整个集合更好吗?
【问题讨论】: