DEV Community

loading...
Cover image for DotVVM Controls : GridView
DotVVM

DotVVM Controls : GridView

Amir Ismail
.Net Team Leader | Passionate about software development | Co-Organizer in Azure Egypt & Azure Kuwait Meetup groups | DotVVM Developer Advocate
Updated on ・4 min read

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.

public class Student
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime EnrollmentDate { get; set; }
}    

in ViewModel class

public List<Student> Students { get; set; }

in dothtml file

<dot:GridView DataSource="{value: Students}" class="page-grid">
    <Columns>
         <dot:GridViewTextColumn ValueBinding="{value: FirstName}" HeaderText="First Name" />
         <dot:GridViewTextColumn ValueBinding="{value: LastName}" HeaderText="Last Name" />
         <dot:GridViewTextColumn ValueBinding="{value: EnrollmentDate}" HeaderText="Enrollment Date" />
    </Columns>
</dot:GridView>

we used GridViewTextColumn for all fields and used ValueBinding attribute to specify which property is going to be rendered in that column.
Alt Text

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

<dot:GridViewTextColumn ValueBinding="{value: EnrollmentDate}" 
 FormatString="yyyy-MM-dd" 
 HeaderText="Enrollment Date" />

Alt Text

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).

public GridViewDataSet<Student> Students { get; set; } = new GridViewDataSet<StudentListModel>()
   {
      RowEditOptions = { PrimaryKeyPropertyName = "Id" }
   };

In PreRender method populate your GridViewDataSet<Student>

public override async Task PreRender()
{
     if (Students.IsRefreshRequired)
     {
         var queryable = await _studentService.GetAllStudentsAsync();
         Students.LoadFromQueryable(queryable.AsQueryable());
     }
     await base.PreRender();
}

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

<dot:GridView DataSource="{value: Students}" class="page-grid" InlineEditing="true">
  <Columns>
    <dot:GridViewTextColumn ValueBinding="{value: FirstName}" HeaderText="First Name" />
    <dot:GridViewTextColumn ValueBinding="{value: LastName}" HeaderText="Last Name" />
    <dot:GridViewTextColumn ValueBinding="{value: EnrollmentDate}"
       IsEditable="false"
       HeaderText="Enrollment Date" FormatString="yyyy-MM-dd" />
    <dot:GridViewTemplateColumn>
        <ContentTemplate>
           <dot:Button class Text="Edit" Click="{command: _parent.Edit(_this)}" />
        </ContentTemplate>
        <EditTemplate>
           <dot:Button Text="Save" Click="{command: _parent.Update(_this)}" />
           <dot:Button Text="Cancel" Click="{command: _parent.Cancel()}" />
        </EditTemplate>
    </dot:GridViewTemplateColumn>
  </Columns>  
</dot:GridView>

We added aGridViewTemplateColumn and specified its ContentTemplate which will be rendered in normal display
Alt Text
and EditTemplate which will be rendered when we click Edit button
Alt Text

_parent is instance of your model object and _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 click on Edit, Save, and cancel buttons.

public void Edit(Student student)
{
     Students.RowEditOptions.EditRowId = student.Id;
}
public void Cancel()
{
     Students.RowEditOptions.EditRowId = null;
     Students.RequestRefresh();
}
public void Update(StudentListModel model)
{
     // code for updating your datastore
     .....
     Students.RowEditOptions.EditRowId = null;
}

When you do inline editing, DotVVM does't refresh the whole page, but it do it via ajax calls.

Nested GridViews

Suppose we want to display student grades in the same row besides his Name. to achieve this, the Student Object should contains a property if type GridViewDataSet for grades List. Then in Prerender() method populate that property for each Student object.

public override async Task PreRender()
{
     if (Students.IsRefreshRequired)
     {
         var queryable = await _studentService.GetAllStudentsAsync();
         queryable.ForEach(x =>
         {
             x.Grades = new GridViewDataSet<Grade>()
             {
                RowEditOptions = { PrimaryKeyPropertyName = "GradeId" }
             };                 
             x.Grades.LoadFromQueryable(x.StudentGrades.AsQueryable());
         });
         Students.LoadFromQueryable(queryable.AsQueryable());
     }
     await base.PreRender();
}

in dothtml file will add a new GridViewTemplateColumn for the inner GridView

<dot:GridViewTemplateColumn HeaderText="Grades" IsEditable="false">
     <dot:GridView DataSource="{value: Grades}" class="page-grid">
          <Columns>
              <dot:GridViewTextColumn ValueBinding="{value: Subject}" HeaderText="Subject" />
              <dot:GridViewTextColumn ValueBinding="{value: Month}" HeaderText="Month" />
              <dot:GridViewTextColumn ValueBinding="{value: Score}" HeaderText="Score" />                            
          </Columns>
     </dot:GridView>
</dot:GridViewTemplateColumn>

Alt Text

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.

Discussion (0)

Forem Open with the Forem app