DotVVM Controls - GridView

 Introduction

 DotVVM Controls - GridView
 
GridView control in DotVVM is very similar to what we used to use in our legacy web forms applications. When you run your DotVVM application, it is getting rendered as a classic HTML table.
 
In DotVVM, you can bind your GridView control by setting DataSource property to IEnumerable<T> or GridViewDataSet<T> object. GridView Control in DotVVM supports inline editing, sorting, and defining your column template.
 

Simple GridView

 
Suppose we want to display a list of students:
  1. public class Student    
  2. {    
  3.      public string FirstName { getset; }    
  4.      public string LastName { getset; }    
  5.      public DateTime EnrollmentDate { getset; }    
  6. }     
in ViewModel class:
  1. public List<Student> Students { getset; }  
in dothtml file:
  1. <dot:GridView DataSource="{value: Students}" class="page-grid">  
  2.     <Columns>  
  3.         <dot:GridViewTextColumn ValueBinding="{value: FirstName}" HeaderText="First Name" />  
  4.         <dot:GridViewTextColumn ValueBinding="{value: LastName}" HeaderText="Last Name" />  
  5.         <dot:GridViewTextColumn ValueBinding="{value: EnrollmentDate}" HeaderText="Enrollment Date" />  
  6.     </Columns>  
  7. </dot:GridView>  
we used GridViewTextColumn for all fields and used ValueBinding attribute to specify which property is going to be rendered in that column.
 
DotVVM Controls - GridView
 
By default, DotVVM is getting the string representation of the specified value and render it.
 

FormatString

 
To specify a specific format for the rendered value, we can do that by setting `FormatString` of the target column. DotVVM is supporting most of .NET format strings
  1. <dot:GridViewTextColumn ValueBinding="{value: EnrollmentDate}"  
  2.                         FormatString="yyyy-MM-dd"  
  3.                         HeaderText="Enrollment Date" />  
DotVVM Controls - GridView
 

Inline Editing

 
In the past when we tried to implement inline editing for a GridView in web forms application we had had to write many lines of code and implement Edit event but in DotVVM it pretty easy to implement it with only one limitation, your data source should be of type GridViewDataSet<T>.
 
IEnumerable<T> is not supported for inline editing.
 
In ViewModel class change the Students property type and Set RowEditOptions.PrimaryKeyPropertyName to your list unique key(in our case is Id).
  1. public GridViewDataSet<Student> Students { getset; } = new GridViewDataSet<StudentListModel>()  
  2.    {  
  3.         RowEditOptions = { PrimaryKeyPropertyName = "Id" }  
  4.    };  
In the PreRender() method populate your GridViewDataSet<Student>
  1. public override async Task PreRender()  
  2. {  
  3.     if (Students.IsRefreshRequired)  
  4.     {  
  5.         var studentsList = await _studentService.GetAllStudentsAsync();  
  6.         Students.LoadFromQueryable(studentsList.AsQueryable());  
  7.     }  
  8.     await base.PreRender();  
  9. }  
In dothtml file, set InlineEditing attribute of your GridView to true. By default DotVVM is allowing all columns to be editable. If you want to prevent a specific column to be edited you need to set its IsEditable attribute to false.
  1. <dot:GridView DataSource="{value: Students}" class="page-grid" InlineEditing="true">  
  2.    <Columns>  
  3.       <dot:GridViewTextColumn ValueBinding="{value: FirstName}" HeaderText="First Name" />  
  4.       <dot:GridViewTextColumn ValueBinding="{value: LastName}" HeaderText="Last Name" />  
  5.       <dot:GridViewTextColumn ValueBinding="{value: EnrollmentDate}" HeaderText="Enrollment Date" FormatString="yyyy-MM-dd"
  6.                               IsEditable="false" />  

  7.       <dot:GridViewTemplateColumn>  
  8.          <ContentTemplate>  
  9.             <dot:Button class Text="Edit" Click="{command: _parent.Edit(_this)}" />  
  10.          </ContentTemplate>  
  11.          <EditTemplate>  
  12.             <dot:Button Text="Save" Click="{command: _parent.Update(_this)}" />  
  13.             <dot:Button Text="Cancel" Click="{command: _parent.Cancel()}" />  
  14.          </EditTemplate>  
  15.       </dot:GridViewTemplateColumn>  
  16.    </Columns>  
  17. </dot:GridView>  
We added a GridViewTemplateColumn and specified its ContentTemplate which will be rendered in normal display
 
DotVVM Controls - GridView
 
and EditTemplate which will be rendered when we click Edit button
 
DotVVM Controls - GridView
  • _parent : is instance of your model object
  • _this which is passed to Edit() and Update() methods is the corresponding item in GridView data source.
In ModelView class we need to add the commands (normal c# method) that will be executed when the user clicks on Edit, Save, and Cancel buttons.
  1. public void Edit(Student student)  
  2. {  
  3.    Students.RowEditOptions.EditRowId = student.Id;  
  4. }  
  5. public void Cancel()  
  6. {  
  7.    Students.RowEditOptions.EditRowId = null;  
  8.    Students.RequestRefresh();  
  9. }  
  10. public void Update(StudentListModel model)  
  11. {  
  12.    // code for updating your datastore  
  13.    .....  
  14.    Students.RowEditOptions.EditRowId = null;  
  15. }  
When you do inline editing, DotVVM doesn't refresh the whole page, but it does it via ajax calls.
 

Nested GridViews

 
Suppose we want to display student's grades in the same row beside his Name. To achieve this, the Student Object should contain a property of type GridViewDataSet for grades List, then in Prerender() method populate that property for each Student object.
  1. public override async Task PreRender()  
  2. {  
  3.    if (Students.IsRefreshRequired)  
  4.    {  
  5.       var studentsList = await _studentService.GetAllStudentsAsync();  
  6.       studentsList.ForEach(x =>  {  
  7.             x.Grades = new GridViewDataSet<Grade>()  {  
  8.                RowEditOptions = { PrimaryKeyPropertyName = "GradeId" }  
  9.             };  
  10.             x.Grades.LoadFromQueryable(x.StudentGrades.AsQueryable());  
  11.        });  
  12.       Students.LoadFromQueryable(studentsList.AsQueryable());  
  13.    }  
  14.    await base.PreRender();  
  15. }  
In dothtml file will add a new GridViewTemplateColumn for the inner GridView
  1. <dot:GridViewTemplateColumn HeaderText="Grades" IsEditable="false">  
  2.    <dot:GridView DataSource="{value: Grades}" class="page-grid">  
  3.       <Columns>  
  4.          <dot:GridViewTextColumn ValueBinding="{value: Subject}" HeaderText="Subject" />  
  5.          <dot:GridViewTextColumn ValueBinding="{value: Month}" HeaderText="Month" />  
  6.          <dot:GridViewTextColumn ValueBinding="{value: Score}" HeaderText="Score" />  
  7.       </Columns>  
  8.    </dot:GridView>  
  9. </dot:GridViewTemplateColumn>  
DotVVM Controls - GridView
 

Summary

 
In this article, we demonstrated how to use DotVVM GridView control and how it is pretty easy to bind your collection to it, enable inline editing without re-loading the whole page and how to render nested GridViews with few line of code.