Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/267.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 过滤ICollectionView时性能较慢<;对象>;_C#_Wpf_Performance_Mvvm_Data Binding - Fatal编程技术网

C# 过滤ICollectionView时性能较慢<;对象>;

C# 过滤ICollectionView时性能较慢<;对象>;,c#,wpf,performance,mvvm,data-binding,C#,Wpf,Performance,Mvvm,Data Binding,在使用MVVM的WPF应用程序中,我查询数据库以获取客户端的ObservableCollection,创建ICollectionView并应用筛选函数 在usercontrol上,我将用于过滤器的文本绑定到文本框,将ICollectionView绑定到列表框 ICollectionView最初包含1104个客户端(仅ClientID和ClientName) 从数据库检索数据非常快。但是,列表框填充大约需要4秒钟 当我在过滤器中输入文本时,如果要返回的客户端数量较低,则列表框会相对较快地重新绘制。

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

在usercontrol上,我将用于过滤器的文本绑定到文本框,将ICollectionView绑定到列表框

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

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

当我在过滤器中输入文本时,如果要返回的客户端数量较低,则列表框会相对较快地重新绘制。但是,如果我清除了文本框,则需要另外4秒来重新绘制

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

谢谢你的建议/帮助

视图:


视图模型:

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));
        }
    }
}
使用ClientReports.Common.Infrastructure.Models;
使用ClientReports.Common.Infrastructure.Services;
使用Prism.Mvvm;
使用制度;
使用System.Collections.ObjectModel;
使用系统组件模型;
使用System.Threading.Tasks;
使用System.Windows.Data;
命名空间ClientReports.Module.SchemeSelection.ViewModels
{
公共类ClientsViewModel:BindableBase
{
专用IClientService客户端服务;
public ClientsViewModel(){}
公共客户端视图模型(IClientService客户端服务)
{
this.clientService=clientService;
Clients=新的observeCollection();
GetClients().ContinueWith(x=>{});
}
公共ObservableCollection客户端{get;}
公共ICollectionView客户端过滤{get;set;}
私有字符串clientFilter;
公共字符串搜索
{
get=>clientFilter;
设置
{
clientFilter=值;
ClientsFiltered.Refresh();
RaisePropertyChanged(“客户过滤”);
}
}
专用布尔过滤器(客户端)
{
返回搜索==null
||client.ClientName.IndexOf(Search,StringComparison.OrdinalIgnoreCase)!=-1;
}
私有异步任务GetClients()
{
var clients=await clientService.GetAllAsync();
foreach(客户机中的var客户机)
{
客户。添加(客户);
}
ClientsFiltered=CollectionViewSource.GetDefaultView(客户端);
ClientsFiltered.Filter=新谓词(c=>Filter(c作为客户机));
}
}
}

填充ListBox可能需要4秒钟,因为未启用虚拟化,所以WPF必须创建1104个ListBoxItems(并在清除筛选器时重新创建它们)。默认情况下,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>

如果没有帮助,您可以尝试设置列表框的固定高度,然后再次选中


如果这也没有帮助,请检查Microsoft关于虚拟化的文档,原因可能是:

我在构造函数中偶然发现了这一行:
GetClients().ContinueWith(x=>{})。别那么做。改为阅读:谢谢@ChristianMurschall。我已经接受了这一点,并根据这篇文章重写了代码。@ChristianMurschall,这没有帮助。没有任何解释来支持您的陈述,并且链接的文章对
ContinueWith
.Hi@richarp没有任何引用,因为您使用的是CollectionView和您可能感兴趣的筛选设置筛选器、SortDescriptions或GroupDescriptions属性时;出现刷新。设置其中一个属性后,不必立即调用Refresh方法。有关如何延迟自动刷新的信息,请参阅延迟刷新。“来源:[link][/link]@DonBoitnott我同意我的评论缺乏解释。但由于构造函数中的异步操作不是OPs问题,我认为链接可能是“后文式”的。顺便说一句,他的代码在图3中的链接文章中有解释,不是吗?谢谢@Pavel。我一使用您的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>