Implementing the RowViewModel – Part 2

Part 2 – Getting Data into the Grid

In Part 1, we setup the projects necessary for a standard business application using IdeaBlade DevForce for the Model, MVVM Light for the ModelView and a Telerik RadGridView in the View.

In Part 3, we will follow through the binding process to see some of the challenges posed when making the grid editable.

In Part 2, we will make the changes necessary to make the grid editable.

Requirements

For this part of the sample, the requirements are as follows:

  1. Show Orders in the Rows of the Grid.
  2. Make the Grid Editable.
  3. Save changes to the Orders with a Save Changes button.

Showing the Orders in the Grid

This will require adding an Orders property to the MainViewModel; populating that property and then binding the Orders property to the grid.

  1. Make sure there is a reference in the Web project to the server-side Model project.
  2. Open the MainViewModel.cs file.
  3. Remove the Welcome property.
  4. Open the ViewModel\MainViewModel.cs file.
  5. Use the mvvminpc Snippet to add an Orders property.
    /// <summary>
    /// The <see cref="Orders" /> property's name.
    /// </summary>
    public const string OrdersPropertyName = "Orders";
    
    private ObservableCollection<order> _orders;
    
    /// <summary>
    /// Gets the Orders property.
    /// TODO Update documentation:
    /// Changes to that property's value raise the PropertyChanged event. 
    /// This property's value is broadcasted by the Messenger's default instance when it changes.
    /// </summary>
    public ObservableCollection<order> Orders
    {
        get
        {
            return _orders;
        }
    
        set
        {
            if (_orders == value)
            {
                return;
            }
    
            //var oldValue = _orders;
            _orders = value;
    
            // Remove one of the two calls below
            //throw new NotImplementedException();
    
            // Update bindings, no broadcast
            RaisePropertyChanged(OrdersPropertyName);
    
            // Update bindings and broadcast change using GalaSoft.MvvmLight.Messenging
            //RaisePropertyChanged(OrdersPropertyName, oldValue, value, true);
        }
    }
  6. Next, add a method to fill the collection.
    private void GetOrdersAsync()
    {
        var em = new NorthwindIBEntities();
        var qry = em.Orders;
        em.ExecuteQueryAsync(qry, args =>
             this.Orders = new ObservableCollection<order>(args.Results));
    }
  7. Next, add a call to the new method in MainViewModel constructor:
    public MainViewModel() 
    { 
        GetOrdersAsync();
  8. Finally, add a binding to the XAML to show the Orders in the Grid.  (Set the ItemsSource of the RadGridView to Orders.)
    <telerik:RadGridView Name="radGridView1" ItemsSource="{Binding Path=Orders}" Height="775" Width="1000" />
  9. Build and Run.  After a moment or two, you should see the grid, fully populated with Orders.
    image

Making the Grid Editable

For once, the default behavior is desirable.  We get this for free because the RadGridView is editable by default.  Due to the magic of Binding, the Order objects are getting updated whenever a cell in the grid is edited.

Saving the Changes

Saving those changes will require us to have a button bound to an ICommand that will tell the EntityManager to save all the changes.

  1. In MainPage.xaml, add a button to the StackPanel above (or below) the RadGridView.
    <Button Content="Save" Height="23" Name="SaveAllButton" Width="75" HorizontalAlignment="Left" />
  2. In MainViewModel.cs, add a new RelayCommand named SaveAllCommand.
    public RelayCommand SaveAllCommand
    {
        get;
    	private set;
    }
  3. In the MainViewModel constructor, add a line to instantiate the command:
    SaveAllCommand = new RelayCommand(this.SaveAllOrders);
  4. Now add the SaveAllOrders method and the SaveAllButtonEnabled property:
    private void SaveAllOrders()
    {
        this.SaveAllButtonEnabled = false;
        _entityManager.SaveChangesAsync(args => 
            this.SaveAllButtonEnabled = true);
    }
    
    public bool SaveAllButtonEnabled
    {
        get
        {
            return _saveAllButtonEnabled;
        }
        set
        {
            _saveAllButtonEnabled = value;
            RaisePropertyChanged("SaveAllButtonEnabled");
        }
    }
  5. Now you can go back to the button to set the bindings:
    <Button Content="Save" Height="23" Name="SaveAllButton" Width="75" HorizontalAlignment="Left" IsEnabled="{Binding Path=SaveAllButtonEnabled}" Command="{Binding Path=SaveAllCommand}" />
  6. Build and Run. After a moment or two, you should see the grid, fully populated with Orders. Try editing some of the orders and hit Save All. Refresh the page to see that the changes were saved.

What’s next?

So now you have an editable grid. So far, we have not needed the RowViewModel. If you only want SaveAll functionality, the default behavior of the grid will suffice. The grid lets you edit any cell all the time and the bindings keep the model up to date. A simple call to entity manager to save the changes and all is well.
However, if you want some entity specific functionality, you will find it quite cumbersome to try to deal with this within the context of the grid’s ViewModel as it is really only concerned with the grid and entire grid related actions (such as Save All).

In Part 3, we will add some entity specific requirements so we can see how to use the RowViewModel to make working with the entities in the grid much simpler.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s

This site uses Akismet to reduce spam. Learn how your comment data is processed.