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.
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" />
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
and EditTemplate
which will be rendered when we click Edit button
_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>
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.
Top comments (0)