Collin Barrett
Collin Barrett

Reputation: 2569

Bind grid to an IEnumerable in the view's viewmodel

I am building a user profile page for an application. The page allows the user to view and edit basic data fields (last name, first name, etc.). Also, there is a grid of users to whom they are linked. The user should be able to perform some basic CRUD operations on this grid. How can I bind this grid to an IEnumerable (or comparable) that is passed to the view as a property of the viewmodel?

The view model is something like this:

using System.Collections.Generic;

namespace Pricing.Models.ViewModel
{
    public class UserProfileUpdateViewModel
    {
        public int UserId { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public IEnumerable<LinkedUserViewModel> LinkedUsers { get; set; }
    }
}

My user profile view currently looks something like the following. Note the TODO comment on line #38 which marks what is currently broken.

@model Pricing.Models.ViewModel.UserProfileUpdateViewModel
<div class="panel-body">
    <h2>User Profile</h2>
    @using (Html.BeginForm("UpdateProfile", "Account", FormMethod.Post))
    {
        @Html.AntiForgeryToken()
        @Html.HiddenFor(profile => profile.UserId)
        <div class="form-horizontal">
            <div class="form-group">
                <label class="control-label col-md-2">Username</label>
                <div class="col-md-10" style="padding-top:7px">
                    @User.Identity.Name
                </div>
            </div>
        </div>
        <div class="form-horizontal">
            <div class="form-group">
                @Html.LabelFor(profile => profile.FirstName, "First Name", new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(profile => profile.FirstName, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(profile => profile.FirstName, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>
        <div class="form-horizontal">
            <div class="form-group">
                @Html.LabelFor(profile => profile.LastName, "Last Name", new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    @Html.EditorFor(profile => profile.LastName, new { htmlAttributes = new { @class = "form-control" } })
                    @Html.ValidationMessageFor(profile => profile.LastName, "", new { @class = "text-danger" })
                </div>
            </div>
        </div>
        <div class="form-horizontal">
            <div class="form-group">
                @Html.LabelFor(profile => profile.LinkedUsers, "Linked Users", new { @class = "control-label col-md-2" })
                <div class="col-md-10">
                    //TODO: This bind fails, I need to bind to the IENumerable property of UserProfileUpdateViewModel
                    @(Html.Kendo().Grid<Freds.Retail.DirectPricing.Models.ViewModel.UserProfileUpdateViewModel>()
                        .Name("LinkedUsers")
                        .ToolBar(tools =>
                        {
                            tools.Create().Text("Add Linked User");
                        })
                        .Editable(editable => editable.Mode(GridEditMode.InCell).CreateAt(GridInsertRowPosition.Bottom).DisplayDeleteConfirmation(false))
                        .Columns(columns =>
                        {
                            columns.Bound(p => p.LinkedUsersId).Visible(false).ClientTemplate("#= Id #" +
                            "<input type='hidden' name='LinkedUsers[#= index(data) #].Id' value='#= Id #' />"
                            );
                            columns.Bound(p => p.LinkedUserName).Visible(false).ClientTemplate("#= LinkedUserName #" +
                            "<input type='hidden' name='LinkedUsers[#= index(data) #].LinkedUserName' value='#= LinkedUserName #' />"
                            );
                            columns.Command(command => command.Destroy()).Width(110);
                        })
                        .Scrollable()
                        .Sortable()
                        .HtmlAttributes(new { style = "width:75%" })
                        .DataSource(source => source
                            .Ajax()
                            .Model(model =>
                            {
                                model.Id(d => d.Id);
                            })
                            .Batch(true)
                            .ServerOperation(false)
                            .Events(events => events.Error("error_handler"))
                            .Read(read => read.Action("LinkedUser_Read", "Account"))
                        )
                    )
                </div>
            </div>
        </div>
        <div class="form-horizontal">
            <div class="form-group">
                <label class="control-label col-md-2"></label>
                <div class="col-md-10">
                    <input type="submit" value="Save Changes" class="btn btn-default" />
                </div>
            </div>
        </div>
    }
</div>

Upvotes: 0

Views: 1407

Answers (1)

Ahmed
Ahmed

Reputation: 1590

You should pass IEnumerable itself not the type.

@(Html.Kendo().Grid<Model.LinkedUsers>()

Upvotes: 4

Related Questions