如何将搜索应用于 MVVM (WPF) 中的列表而不每次都调用列表值?

How to apply search to the list in the MVVM (WPF) without recalling the list values every time?

首先,我是 MVVM 的新手,如果我遗漏了重点,请随时纠正我。

我正在开发使用 MVVM 社区工具包的 WPF 应用程序。我的应用程序架构看起来更像这样:

  1. 我有简单的 Model 包含一些基本属性
public class Package : ObservableObject
    {
        private string id;
        public string Id
        {
            get => id;
            set => SetProperty(ref id, value);
        }

        private string name;
        public string Name
        {
            get => name;
            set => SetProperty(ref name, value);
        }

        private string version;
        public string Version
        {
            get => version;
            set => SetProperty(ref version, value);
        }

        private string summary;
        public string Summary
        {
            get => summary;
            set => SetProperty(ref summary, value);
        }
}
  1. ViewModel,其中有 IList<Package> 属性 和 AsyncRelayCommand 调用进程,获取输出并更新 属性。
class MainWindowViewModel : ObservableObject
    {
        public AsyncRelayCommand StartProcessCommand { get; }
        public MainWindowViewModel()
        {
            
            StartProcessCommand = new AsyncRelayCommand(StartProcess, CanStartProcess);
            
        }
        
        private async Task StartProcess()
        {
            
           //Start process, collect the output and set the PackageList property
        }

        private IList<Package> packagesList;

        public IList<Package> PackagesList
        {
            get => packagesList;
            set => SetProperty(ref packagesList, value);
        }
 }
  1. 然后有一个View绑定如下:

<ListView ItemsSource="{Binding PackagesList, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
               
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}"/>
                        <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
                        <GridViewColumn Header="Version" DisplayMemberBinding="{Binding Version}" />
                        <GridViewColumn Header="Summary" DisplayMemberBinding="{Binding Summary}"/>
                    </GridView>
                </ListView.View>
            </ListView>

和调用 RelayCommand 的按钮(异步)。

这是我面临的问题

我想应用搜索 TextBox 来动态搜索 IList<Package> 的结果,为此我在 ViewModel 中创建了一个 SearchTextPropertyChanged 事件上更新 IList<Package> 属性。问题是我的 属性 正在改变,我想 不记得 每次都从过程中回忆它。

  1. 创建列表
  2. 搜索列表并将其呈现在视图中
  3. 如果我要删除我的 searchText 值,它仍然显示从点 1 开始的列表

实现此目标的最佳方法是什么?

到目前为止我已经到了,但只工作了一次,过滤列表但不返回到之前的列表:



public void SearchItem()
        {
            PackagesList = packagesList.Where(package => package.Id == SearchText).ToList();

        }

private string? searchText;
        public string? SearchText
        {
            get => searchText;
            set
            {
                SetProperty(ref searchText, value);
                SearchItem();
            }
            
        }

按照你的说法,你想在删除文本后显示所有数据? 如果是这样,你可以试试这个

public void SearchItem()
{   
    PackagesList = packagesList.Where(package => package.Id == SearchText || null == SearchText).ToList();
}

MainWindowViewModel 中创建另一个 属性 IList<Package> 并将其命名为 ResultList

    private IList<Package> ResultList { get; set;} // Add Result list
    private IList<Package> packagesList;

    public IList<Package> PackagesList
    {
        get => packagesList;
        set => SetProperty(ref packagesList, value);
    }

改为将 ItemsSource 绑定设置为 ResultList

        <ListView ItemsSource="{Binding ResultList, Mode=OneWay, UpdateSourceTrigger=PropertyChanged}">
           
            <ListView.View>
                <GridView>
                    <GridViewColumn Header="Id" DisplayMemberBinding="{Binding Id}"/>
                    <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
                    <GridViewColumn Header="Version" DisplayMemberBinding="{Binding Version}" />
                    <GridViewColumn Header="Summary" DisplayMemberBinding="{Binding Summary}"/>
                </GridView>
            </ListView.View>
        </ListView>

任何时候您设置 PackagesList,您也会设置 ResultList。现在,当它进入搜索时,你会做一些这样的事情

public void SearchItem()
{
    ResultList = packagesList.Where(package => package.Id == SearchText).ToList();
}