如何将搜索应用于 MVVM (WPF) 中的列表,而无需每次都调用列表值?
Posted
技术标签:
【中文标题】如何将搜索应用于 MVVM (WPF) 中的列表,而无需每次都调用列表值?【英文标题】:How to apply search to the list in the MVVM (WPF) without recalling the list values every time? 【发布时间】:2022-01-14 07:14:34 【问题描述】:首先,我是 MVVM 的新手,但如果我遗漏了要点,请随时纠正我。
我正在开发使用 MVVM 社区工具包的 WPF 应用程序。我的应用架构看起来更像这样:
-
我有简单的
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);
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);
-
然后有一个
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
中创建了一个SearchText
,它更新了@987654336 上的IList<Package>
属性@ 事件。问题是我的财产正在发生变化,我想不记得每次都从这个过程中。
-
创建列表
搜索列表并将其显示在视图中
如果我删除了我的 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();
【问题讨论】:
docs.microsoft.com/en-us/dotnet/desktop/wpf/data/… 请尽量减少问题。 ***.com/help/minimal-reproducible-example 创建一个IList<Package>
并将其命名为ResultList
或任何名称。将您的ItemsSource
绑定设置为ResultList
。任何时候你设置PackagesList
,你也设置ResultList
。现在当它进入搜索时,你会做这种ResultList = packagesList.Where(package => package.Id == SearchText).ToList();
@Jeffery 谢谢你的建议。这样就解决了问题!
@user8909887 我将其发布为答案。将其标记为帮助他人的答案
【参考方案1】:
在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();
【讨论】:
【参考方案2】:根据您的说法,您想在删除文本后显示所有数据吗? 如果是这样,你可以试试这个
public void SearchItem()
PackagesList = packagesList.Where(package => package.Id == SearchText || null == SearchText).ToList();
【讨论】:
以上是关于如何将搜索应用于 MVVM (WPF) 中的列表,而无需每次都调用列表值?的主要内容,如果未能解决你的问题,请参考以下文章
使用 MVVM 从 WPF ListView 项触发双击事件
如何在 MVVM 中的 UserControl 之间进行通信 - WPF 应用程序
将 WPF ValidationRule 的状态传递给 MVVM 中的视图模型