This is the continuation from Part 1 where I walked through creating my Model. The next step is to create a View and a View Model. There should only be one View Model per View. I will try to take advantage of xaml binding where possible.
Following is my View Model.
- Imports System.Collections.ObjectModel
- Imports System.ComponentModel
- Public Class EmployeeMaintenanceViewModel
- Implements INotifyPropertyChanged
- Public Event PropertyChanged( _
- ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
- Protected Sub NotifyPropertyChanged(ByVal propertyName As String)
- RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
- End Sub
- #Region "Private Members"
- Private _employeeGateway As EmployeeGateway
- Private _currentRowCache As EmployeeModel
- Private _employeeList As ObservableCollection(Of EmployeeModel) = _
- New ObservableCollection(Of EmployeeModel)
- #End Region
- #Region "Constructors"
- Public Sub New()
- End Sub
- #End Region
- #Region "Properties"
- Public Property CurrentRowCache() As EmployeeModel
- Get
- Return _currentRowCache
- End Get
- Set(ByVal value As EmployeeModel)
- _currentRowCache = value
- End Set
- End Property
- Public Property EmployeeList() As ObservableCollection(Of EmployeeModel)
- Get
- Return _employeeList
- End Get
- Set(ByVal value As ObservableCollection(Of EmployeeModel))
- _employeeList = value
- End Set
- End Property
- #End Region
- #Region "Public Methods"
- 'use WCF to load all employees.
- Public Sub Load()
- 'clear the list prior to loading.
- EmployeeList.Clear()
- _employeeGateway = New EmployeeGateway()
- _employeeGateway.FindAllEmployees(AddressOf OnEmployeesLoaded)
- End Sub
- Public Function GetNewEmployee() As EmployeeModel
- Dim emp As New EmployeeModel()
- 'default to active, set uniqueId to map employee back
- 'when returned from a save
- emp.IsActive = True
- emp.UniqueId = Guid.NewGuid
- Return emp
- End Function
- Public Sub UpdateEmployee(ByVal emp As EmployeeModel)
- emp.IsModified = True
- SaveEmployee(emp)
- End Sub
- Public Sub DeleteEmployee(ByVal id As Integer)
- Dim emp As EmployeeModel = EmployeeList.Where(Function(x) x.Id = id).SingleOrDefault()
- If id > 0 Then
- emp.IsDeleted = True
- SaveEmployee(emp)
- Else
- EmployeeList.Remove(emp)
- End If
- End Sub
- 'in a case of a cancel edit, i reload employee with the values stored in the
- 'row cache before edit.
- Public Sub ReloadEmployeeFromCache(ByVal emp As EmployeeModel)
- If CurrentRowCache Is Nothing Then
- Exit Sub
- End If
- With emp
- .IsActive = CurrentRowCache.IsActive
- .FirstName = CurrentRowCache.FirstName
- .LastName = CurrentRowCache.LastName
- End With
- End Sub
- #End Region
- #Region "Private Methods"
- 'Call WCF to save employee
- Private Sub SaveEmployee(ByVal emp As EmployeeModel)
- _employeeGateway = New EmployeeGateway()
- _lookupGateway.SaveEmployee(AddressOf OnEmployeeSaved, emp)
- End Sub
- Private Sub UpdateRecord(ByVal updatedEmployee As EmployeeModel)
- Dim emp As EmployeeModel
- 'if uniqueId is not Guid.Empty, it's a new add, use the guid to find it in the list.
- If updatedEmployee.UniqueId <> Guid.Empty Then
- emp = EmployeeList.Where(Function(l) l.UniqueId = _
- updatedEmployee.UniqueId).SingleOrDefault
- Else
- emp = EmployeeList.Where(Function(l) l.Id = _
- updatedEmployee.Id).SingleOrDefault
- End If
- 'check if employee was found
- If emp IsNot Nothing Then
- If updatedEmployee.IsDeleted Then
- EmployeeList.Remove(emp)
- Else
- 'This data will be updated on the grid since I implemented
- 'INotifiyPropertyChanged interface on my Model.
- With emp
- .Id = updatedEmployee.Id
- .FirstName = updatedEmployee.FirstName
- .LastName = updatedEmployee.LastName
- .IsActive = updatedEmployee.IsActive
- End With
- End If
- End If
- End Sub
- #End Region
- #Region "Event Handlers"
- Private Sub OnEmployeesLoaded(ByVal employees As ObservableCollection(Of EmployeeModel))
- 'each employee must be added to the observable collection so that
- 'it is reflected on the Grid.
- For Each emp As EmployeeModel In employees
- EmployeeList.Add(emp)
- Next
- End Sub
- Public Sub OnEmployeeSaved(ByVal updatedEmployee As EmployeeModel)
- If updatedEmployee IsNot Nothing Then
- UpdateRecord(updatedEmployee)
- End If
- End Sub
- #End Region
- End Class
Review the comments in the code snippet for explanation. The goal is to place all the logic specific to UI in the View Model. The View Model should not be accessing any controls directly. The View knows about the View Model, but the View Model does not have a reference back to the View. The View Model basically bridges the gap between the View and the Model.
The View code behind will access controls in a case where direct binding is not available, but any logic should still be placed in the View Model. The View code behind will generaly handle events and make calls to the View Model. I will cover that in Part 3 of the post.
