Jan 23

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.

View Model
  1. Imports System.Collections.ObjectModel
  2. Imports System.ComponentModel
  3.  
  4. Public Class EmployeeMaintenanceViewModel
  5.     Implements INotifyPropertyChanged
  6.  
  7.     Public Event PropertyChanged( _
  8.             ByVal sender As Object, ByVal e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
  9.  
  10.     Protected Sub NotifyPropertyChanged(ByVal propertyName As String)
  11.         RaiseEvent PropertyChanged(Me, New PropertyChangedEventArgs(propertyName))
  12.     End Sub
  13.  
  14. #Region "Private Members"
  15.  
  16.     Private _employeeGateway As EmployeeGateway
  17.     Private _currentRowCache As EmployeeModel
  18.     Private _employeeList As ObservableCollection(Of EmployeeModel) =  _
  19.             New ObservableCollection(Of EmployeeModel)
  20.  
  21. #End Region
  22.  
  23. #Region "Constructors"
  24.  
  25.     Public Sub New()
  26.  
  27.     End Sub
  28.  
  29. #End Region
  30.  
  31. #Region "Properties"
  32.  
  33.     Public Property CurrentRowCache() As EmployeeModel
  34.         Get
  35.             Return _currentRowCache
  36.         End Get
  37.         Set(ByVal value As EmployeeModel)
  38.             _currentRowCache = value
  39.         End Set
  40.     End Property
  41.  
  42.     Public Property EmployeeList() As ObservableCollection(Of EmployeeModel)
  43.         Get
  44.             Return _employeeList
  45.         End Get
  46.         Set(ByVal value As ObservableCollection(Of EmployeeModel))
  47.             _employeeList = value
  48.         End Set
  49.     End Property
  50.  
  51. #End Region
  52.  
  53. #Region "Public Methods"
  54.  
  55.     'use WCF to load all employees.
  56.     Public Sub Load()
  57.         'clear the list prior to loading.
  58.         EmployeeList.Clear()
  59.  
  60.         _employeeGateway = New EmployeeGateway()
  61.         _employeeGateway.FindAllEmployees(AddressOf OnEmployeesLoaded)
  62.  
  63.     End Sub
  64.  
  65.     Public Function GetNewEmployee() As EmployeeModel
  66.         Dim emp As New EmployeeModel()
  67.  
  68.         'default to active, set uniqueId to map employee back
  69.         'when returned from a save
  70.         emp.IsActive = True
  71.         emp.UniqueId = Guid.NewGuid
  72.         Return emp
  73.     End Function
  74.  
  75.     Public Sub UpdateEmployee(ByVal emp As EmployeeModel)
  76.         emp.IsModified = True
  77.         SaveEmployee(emp)
  78.     End Sub
  79.  
  80.     Public Sub DeleteEmployee(ByVal id As Integer)
  81.         Dim emp As EmployeeModel = EmployeeList.Where(Function(x) x.Id = id).SingleOrDefault()
  82.         If id > 0 Then
  83.             emp.IsDeleted = True
  84.             SaveEmployee(emp)
  85.         Else
  86.             EmployeeList.Remove(emp)
  87.         End If
  88.  
  89.     End Sub
  90.  
  91.     'in a case of a cancel edit, i reload employee with the values stored in the
  92.     'row cache before edit.
  93.     Public Sub ReloadEmployeeFromCache(ByVal emp As EmployeeModel)
  94.         If CurrentRowCache Is Nothing Then
  95.             Exit Sub
  96.         End If
  97.  
  98.         With emp
  99.             .IsActive = CurrentRowCache.IsActive
  100.             .FirstName = CurrentRowCache.FirstName
  101.             .LastName = CurrentRowCache.LastName
  102.         End With
  103.     End Sub
  104.  
  105. #End Region
  106.  
  107. #Region "Private Methods"
  108.  
  109.     'Call WCF to save employee
  110.     Private Sub SaveEmployee(ByVal emp As EmployeeModel)
  111.         _employeeGateway = New EmployeeGateway()
  112.         _lookupGateway.SaveEmployee(AddressOf OnEmployeeSaved, emp)
  113.     End Sub
  114.  
  115.     Private Sub UpdateRecord(ByVal updatedEmployee As EmployeeModel)
  116.         Dim emp As EmployeeModel
  117.  
  118.         'if uniqueId is not Guid.Empty, it's a new add, use the guid to find it in the list.
  119.         If updatedEmployee.UniqueId <> Guid.Empty Then
  120.             emp = EmployeeList.Where(Function(l) l.UniqueId = _
  121.                                          updatedEmployee.UniqueId).SingleOrDefault
  122.         Else
  123.             emp = EmployeeList.Where(Function(l) l.Id = _
  124.                                          updatedEmployee.Id).SingleOrDefault
  125.         End If
  126.  
  127.         'check if employee was found
  128.         If emp IsNot Nothing Then
  129.             If updatedEmployee.IsDeleted Then
  130.                 EmployeeList.Remove(emp)
  131.             Else
  132.                 'This data will be updated on the grid since I implemented
  133.                 'INotifiyPropertyChanged interface on my Model.
  134.                 With emp
  135.                     .Id = updatedEmployee.Id
  136.                     .FirstName = updatedEmployee.FirstName
  137.                     .LastName = updatedEmployee.LastName
  138.                     .IsActive = updatedEmployee.IsActive
  139.                 End With
  140.             End If
  141.         End If
  142.     End Sub
  143.  
  144. #End Region
  145.  
  146. #Region "Event Handlers"
  147.  
  148.     Private Sub OnEmployeesLoaded(ByVal employees As ObservableCollection(Of EmployeeModel))
  149.  
  150.         'each employee must be added to the observable collection so that
  151.         'it is reflected on the Grid.
  152.         For Each emp As EmployeeModel In employees
  153.             EmployeeList.Add(emp)
  154.         Next
  155.  
  156.     End Sub
  157.  
  158.     Public Sub OnEmployeeSaved(ByVal updatedEmployee As EmployeeModel)
  159.         If updatedEmployee IsNot Nothing Then
  160.             UpdateRecord(updatedEmployee)
  161.         End If
  162.     End Sub
  163.  
  164. #End Region
  165.  
  166. 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.

2 Responses to “Silverlight Telerik Editable GridView with MVVM – Part 2”

  1. Cesar Valencia Lopez says:

    Hi,

    ¿Where is the class EmployeeGateway defined? I tried to reproduce your example, but I didn´t find the EmployeeGateway class. Please, could you tell me where it is?

    Thanks.

  2. admin says:

    I don’t show an example of my gateway class. It is a class I have defined under my App_Code folder which makes a call to the server (via WCF) to get my list of employees.

Leave a Reply

preload preload preload