First of all I'm new to the MVVM though in case I'm missing the point please feel free to corect me.
I'm working on the WPF application where I'm using the MVVM Community Toolkit. My application architecture looks more like this:
- I have simple
Model
containing some basic properties
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);
}
}
- There is
ViewModel
where there isIList<Package>
property and aAsyncRelayCommand
which calls the process, get output and update the property.
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);
}
}
- Then there is a
View
where the binding is done as below:
<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>
and the button to call the RelayCommand (async).
Here is the question and the problem I'm facing
I would like to apply the Search TextBox
to dynamically search the result of the IList<Package>
, for this purpose I have create a SearchText
in the ViewModel
which updates the IList<Package>
property on the PropertyChanged
event. The problem is that my property is changing and I would like to not recall it every time from the process.
- Create a list
- Search the list and present it in a View
- In case I'm removing my searchText value it's still showing the list from the point 1
What will be best approach to achieve this?
This is so far where I got to but works only once, filter the list but not returning to previous list:
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();
}
}
CodePudding user response:
Inside the MainWindowViewModel
create another property IList<Package>
and call it 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);
}
Set your ItemsSource binding to the ResultList
instead.
<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>
Anytime you set your PackagesList
, you set the ResultList
as well. Now when it gets to the search, you do something of this sort
public void SearchItem()
{
ResultList = packagesList.Where(package => package.Id == SearchText).ToList();
}
CodePudding user response:
According to your claim, you want to show all the data after deleting the text? If so, you can try this
public void SearchItem()
{
PackagesList = packagesList.Where(package => package.Id == SearchText || null == SearchText).ToList();
}