Filtering and Refreshing the Displayed Data
In this step you will add functionality to MainViewModel allowing filtering the displayed cars by their manufacturer and refreshing the diplayed data. To do that you will need to implement the appropriate methods and define properties which will expose command objects based on them.
Implementing the required methods
-
Remember the RetrieveCarsToDisplayMethod which you defined in a previous step. If you take a look at it again, you will notice that when retrieving cars it takes into account the CarMakerFilter, and if it is available, retrieves only the cars which comply with it.
private void RetrieveCarsToDisplay() { this.ClearCache(); int? selectedCarId = null; //save the Id of the currently selected car if (this.SelectedCar != null) { selectedCarId = this.SelectedCar.CarID; } if (string.IsNullOrEmpty(this.carMakerFilter)) { //retrieve all cars this.CarsToDisplay = this.context.Cars.ToList(); } else { //retrieve cars which comply to the filter this.CarsToDisplay = this.context.Cars.Where(car => car.Make == this.carMakerFilter).ToList(); } //restore the selected car using its saved Id if (selectedCarId.HasValue) { this.SelectedCar = this.CarsToDisplay.FirstOrDefault(car => car.CarID == selectedCarId); } this.Status = string.Format(STATUS_MESSAGE, this.CarsToDisplay.Count); }
Private Sub RetrieveCarsToDisplay() Me.ClearCache() Dim selectedCarId As Integer? = Nothing 'save the Id of the currently selected car If IsNothing(Me.SelectedCar) = False Then selectedCarId = Me.SelectedCar.CarID End If If String.IsNullOrEmpty(Me.CarMakerFilter) Then 'retrieve all cars Me.CarsToDisplay = Me._context.Cars.ToList() Else 'retrieve cars which comply to the filter Me.CarsToDisplay = Me._context.Cars.Where(Function(car) car.Make = Me.CarMakerFilter).ToList() End If 'restore the selected car using its saved Id If selectedCarId.HasValue Then Me.SelectedCar = Me.CarsToDisplay.FirstOrDefault(Function(car) car.CarID = selectedCarId) End If Me.Status = String.Format(STATUS_MESSAGE, Me.CarsToDisplay.Count) End Sub
-
In MainViewModel add a new method called FilterCars. In this method, all you need to do is call RetrieveCarsToDisplay which will retrieve the cars according to the filter and set the filtering flag. This method will be used in the filter command.
private void FilterCars() { this.RetrieveCarsToDisplay(); this.isFilteringActive = (string.IsNullOrEmpty(this.CarMakerFilter) == false); }
Private Sub FilterCars() Me.RetrieveCarsToDisplay() Me._isFilteringActive = (String.IsNullOrEmpty(Me.CarMakerFilter) = False) End Sub
-
In MainViewModel add a method called ResetFilter. This method will be used to form the reset command - it clears the filter, clears the filtering flag and calls RetrieveCarsToDisplay which will retrieve all cars from the database.
private void ResetFilter() { this.CarMakerFilter = string.Empty; this.isFilteringActive = false; this.RetrieveCarsToDisplay(); }
Private Sub ResetFilter() Me.CarMakerFilter = String.Empty Me._isFilteringActive = False Me.RetrieveCarsToDisplay() End Sub
-
In MainViewModel define a method called CanResetFilter. This method will be used to form the reset command and will decide if it can be executed.
private bool CanResetFilter() { return this.isFilteringActive; }
Private Function CanResetFilter() As Boolean Return Me._isFilteringActive End Function
-
In MainViewModel add a method named Refresh. This method clears the CarMakerFilter if the filtering flag is not raised and calls RetrieveCarsToDisplay, which will retrieve the cars from the database according to the current filter. It will be used to form the refresh command.
private void Refresh() { if (this.isFilteringActive == false) { this.CarMakerFilter = string.Empty; } this.RetrieveCarsToDisplay(); }
Private Sub Refresh() If Me._isFilteringActive = False Then Me.CarMakerFilter = String.Empty End If Me.RetrieveCarsToDisplay() End Sub
Exposing commands to the the view
At this point you have defined the methods required to execute filter, reset and refresh operations. However they are not yet exposed to the view and thus cannot be called. You will need to expose command objects for those methods via properties.
-
In MainViewModel add a property FilterCarsCommand. In its getter, initialize a RelayCommand object based on the FilterCars method and return it.
public RelayCommand FilterCarsCommand { get { this.command = new RelayCommand(this.FilterCars); return this.command; } set { this.command = value; } }
Public Property FilterCarsCommand As RelayCommand Get Me._command = New RelayCommand(AddressOf Me.FilterCars) Return Me._command End Get Set(value As RelayCommand) Me._command = value End Set End Property
-
In MainViewModel add a property ResetFilterCommand. In its getter, initialize a RelayCommand object based on the ResetFilter and CanResetFilter methods and return it.
public RelayCommand ResetFilterCommand { get { this.command = new RelayCommand(this.ResetFilter, this.CanResetFilter); return this.command; } set { this.command = value; } }
Public Property ResetFilterCommand As RelayCommand Get Me._command = New RelayCommand(AddressOf Me.ResetFilter, AddressOf Me.CanResetFilter) Return Me._command End Get Set(value As RelayCommand) Me._command = value End Set End Property
-
In MainViewModel add a property RefreshCommand. In its getter, initialize a RelayCommand object based on the Refresh method and return it.
public RelayCommand RefreshCommand { get { this.command = new RelayCommand(this.Refresh); return this.command; } set { this.command = value; } }
Public Property RefreshCommand As RelayCommand Get Me._command = New RelayCommand(AddressOf Me.Refresh) Return Me._command End Get Set(value As RelayCommand) Me._command = value End Set End Property
Checkpoint
The sample application can now filter the displayed cars by their manufacturer, reset the available filter and refresh the displayed data.