DmitryEfimenko / TwitterBootstrapMvc

Fluent implementation of ASP.NET-MVC HTML helpers for Twitter Bootstrap.
Apache License 2.0
224 stars 79 forks source link

DropDownListFromEnum in a loop #413

Closed ghost closed 8 years ago

ghost commented 8 years ago

Hi Dmitry,

can you help me with this task: What i have:

the ViewModel

public class TicketIndexDetailViewModel
    {
        [Required]
        public int TicketID { get; set; }
        [DisplayName("Ticket Key")]
        public string Key { get; set; }
        [DisplayName("Zusammenfassung")]
        public string Summary { get; set; }
        [DisplayName("Erstellt von")]
        public string ReporterName { get; set; }
        [DisplayName("Zugewiesen an")]
        public string AssigneeName { get; set; }
        [DisplayName("Ticket Status")]
        public TicketState State { get; set; }

        public void InitForLabeling()
        {
            TicketID = -1;
            Key = "Key";
            Summary = "Summary";
            ReporterName = "Name";
            AssigneeName = "Name";
            State = TicketState.Created;
        }
    }

the view:

@model TicketIndexViewModel

@using (Html.Bootstrap().Begin(new Table()))
{
    using (var p = Html.Bootstrap().Begin(new Panel()))
    {
        using (p.BeginHeading())
        {
            @Html.Partial("_TicketLeftFilterPartitial")
        }
        using (p.BeginBody())
        {
            TicketIndexDetailViewModel ticketDummy = new TicketIndexDetailViewModel();
            ticketDummy.InitForLabeling();
            <thead>
                <tr>
                    <th>@Html.Bootstrap().Label(ticketDummy.Key)</th>
                    <th>Summary</th>
                    <th>Reporter</th>
                    <th>Assignee</th>
                    <th>State</th>
                </tr>
            </thead>
            <tbody>
                @foreach (var ticket in Model.Tickets)
                        {
                    <tr>
                        <td>@Html.Bootstrap().ActionLink(@ticket.Key, "Edit").RouteValues(new { ticketID = @ticket.TicketID })</td>
                        <td>@Html.Bootstrap().ActionLink(@ticket.Summary, "Edit").RouteValues(new { ticketID = @ticket.TicketID })</td>
                        <td>@ticket.ReporterName</td>
                        <td>@ticket.AssigneeName</td>
                        <td>@Html.Bootstrap().DropDownListFromEnum("State")</td>
                    </tr>
                }
            </tbody>
        }
    }
}

At the very bottom of the foreach loop i need to Show the value of the State Enum. I get the Exception:

[InvalidOperationException: The sequence has no contains no elements.]

The debugger shows a value: image

DmitryEfimenko commented 8 years ago

What does the TicketIndexViewModel looks like? You are using it as a model in your view, so I don't know if it has property State Also, please make sure to submit formatted questions. It's really painful to read something like what you wrote. There is a "Preview" tab when you create an issue or reply to one.

ghost commented 8 years ago

sorry for the formating and here is the TicketIndexViewModel:

public class TicketIndexViewModel
{
    public IEnumerable<PSW.ViewModels.TicketIndexDetailViewModel> Tickets { get; set; }
    public TicketState CurrentSelectedState { get; set; }
    public Dictionary<TicketState, int> NumberOfTicketsPerState { get; set; }
}
DmitryEfimenko commented 8 years ago

You've got the @Html.Bootstrap().DropDownListFromEnum("State") in a foreach loop. Having it assigned to property "State" will make it try to bind to the un-existing property "State" on "TicketIndexViewModel". Use helper .DropDownListFromEnumFor(model => model...) to avoid these issues. You'll get intellicense hint with all the props that you can use. In this case you'll have to do some trickery with a for loop. Quick untested code:

@for (var i, l = Model.Tickets.Count(); i < l; i++)
{
    <tr>
        <td>@Html.Bootstrap().ActionLink(@ticket.Key, "Edit").RouteValues(new { ticketID = @ticket.TicketID })</td>
        <td>@Html.Bootstrap().ActionLink(@ticket.Summary, "Edit").RouteValues(new { ticketID = @ticket.TicketID })</td>
        <td>@ticket.ReporterName</td>
        <td>@ticket.AssigneeName</td>
        <td>@Html.Bootstrap().DropDownListFromEnumFor(model => model.Tickets[i].State)</td>
    </tr>
}

I don't remember how these things are done exactly, but there are plenty of articles in regard to binding inputs inside a for loop to the view model.

ghost commented 8 years ago

thanks a lot! That was the problem, now i know how to fix such errors.. TwitterBootstrapMVC is worth every cent!

DmitryEfimenko commented 8 years ago

Glad I could point you in the right direction.