gpt4 book ai didi

c# - 过滤 ICollectionView 时性能下降
转载 作者:太空狗 更新时间:2023-10-30 01:29:18 27 4
gpt4 key购买 nike

在使用 MVVM 的 WPF 应用程序中,我查询数据库以获取客户端的 ObservableCollection,创建 ICollectionView 并应用过滤器函数。

在我的用户控件上,我将用于过滤器的文本绑定(bind)到一个文本框,并将 ICollectionView 绑定(bind)到一个列表框。

ICollectionView 最初包含 1104 个客户端(仅 ClientID 和 ClientName)。

从数据库中检索数据非常快。但是,列表框需要大约 4 秒的时间来填充。

当我在过滤器中输入文本时,如果返回的客户数量很少,那么列表框会相对快速地重新绘制。但是,如果我清除文本框,则需要 4 秒才能重新绘制。

我是不是遗漏了什么,或者我的代码写得不是很好。

感谢您的任何建议/帮助。

查看:

<UserControl x:Class="ClientReports.Module.SchemeSelection.Views.Clients"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClientReports.Module.SchemeSelection.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True" >
<Grid>
<StackPanel>
<TextBox materialDesign:HintAssist.Hint="Client Search"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}"/>
<ListBox ItemsSource="{Binding ClientsFiltered}" DisplayMemberPath="ClientName" />
</StackPanel>
</Grid>
</UserControl>

View 模型:

using ClientReports.Common.Infrastructure.Models;
using ClientReports.Common.Infrastructure.Services;
using Prism.Mvvm;
using System;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Threading.Tasks;
using System.Windows.Data;

namespace ClientReports.Module.SchemeSelection.ViewModels
{
public class ClientsViewModel : BindableBase
{
private IClientService clientService;

public ClientsViewModel(){ }

public ClientsViewModel(IClientService clientService)
{
this.clientService = clientService;
Clients = new ObservableCollection<Client>();
GetClients().ContinueWith(x => { });
}

public ObservableCollection<Client> Clients { get; }

public ICollectionView ClientsFiltered { get; set; }

private string clientFilter;

public string Search
{
get => clientFilter;
set
{
clientFilter = value;
ClientsFiltered.Refresh();
RaisePropertyChanged("ClientsFiltered");
}
}

private bool Filter(Client client)
{
return Search == null
|| client.ClientName.IndexOf(Search, StringComparison.OrdinalIgnoreCase) != -1;
}


private async Task GetClients()
{
var clients = await clientService.GetAllAsync();
foreach (var client in clients)
{
Clients.Add(client);
}
ClientsFiltered = CollectionViewSource.GetDefaultView(Clients);
ClientsFiltered.Filter = new Predicate<object>(c => Filter(c as Client));
}
}
}

最佳答案

ListBox 可能需要 4 秒来填充,因为未启用虚拟化,因此 WPF 必须创建 1104 个 ListBoxItem(并在清除过滤器时重新创建它们)。默认情况下,为 ListBox 启用虚拟化,但您有时甚至可能在没有意识到的情况下禁用它。在您的示例中,您的 ListBox 位于垂直的 StackPanel 中,这可能是导致此行为的原因。您可以尝试通过以下方式重写 XAML:

<UserControl x:Class="ClientReports.Module.SchemeSelection.Views.Clients"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:ClientReports.Module.SchemeSelection.Views"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<TextBox materialDesign:HintAssist.Hint="Client Search"
Style="{StaticResource MaterialDesignFloatingHintTextBox}"
Text="{Binding Search, UpdateSourceTrigger=PropertyChanged}"
Grid.Row="0"/>
<ListBox ItemsSource="{Binding ClientsFiltered}"
DisplayMemberPath="ClientName"
Grid.Row="1" />
</Grid>
</UserControl>

如果没有帮助,您可以尝试为您的 ListBox 设置固定高度并再次检查。

如果两者都没有帮助,请查看有关虚拟化的 Microsoft 文档以了解其他可能的原因:https://learn.microsoft.com/en-us/dotnet/framework/wpf/advanced/optimizing-performance-controls

关于c# - 过滤 ICollectionView<object> 时性能下降,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52699681/

27 4 0