Problems with MVC 3 DropDownList() in WebGrid()

2019-04-16 09:23发布

I'm trying to place a DropDownList inside a WebGrid but I can't figure out how to do it :(

Things I've tried:

grid.Column("Id", "Value", format: ((item) =>
   Html.DropDownListFor(item.SelectedValue, item.Colors)))

and

grid.Column(header: "", format: (item => Html.DropDownList("Colors", item.Colors)))

and

grid.Column(header: "", format: Html.DropDownList("Colors"))

and various others but I couldn't get it to work. Any help is much appreciated.

Model

public class PersonViewModel
{
    public string Name { get; set; }
    public int Age { get; set; }
    public SelectList Colors { get; set; }
    public int SelectedValue { get; set; }
}
public class ColorViewModel
{
    public int ColorID { get; set; }
    public string ColorName { get; set; }
}

Controller

public ActionResult Index()
{

    var colorList = new List<ColorViewModel>() {
                        new ColorViewModel() { ColorID = 1, ColorName = "Green" },
                        new ColorViewModel() { ColorID = 2, ColorName = "Red" },
                        new ColorViewModel() { ColorID = 3, ColorName = "Yellow" }
                    };

    var people = new List<PersonViewModel>()
                {
                    new PersonViewModel() {
                        Name = "Foo", 
                        Age = 42, 
                        Colors = new SelectList(colorList)
                    },
                    new PersonViewModel() {
                        Name = "Bar", 
                        Age = 1337, 
                        Colors = new SelectList(colorList)
                    }
                };

    return View(people);
}

View

@model IEnumerable<PersonViewModel>

@{
    var grid = new WebGrid(Model);
}

<h2>DropDownList in WebGrid</h2>
@using (Html.BeginForm())
{
    @grid.GetHtml(
        columns: grid.Columns(
            grid.Column("Name"),
            grid.Column("Age"),
            grid.Column() // HELP - INSERT DROPDOWNLIST
        )
    )    
    <p>
        <button>Submit</button>
    </p>
}

2条回答
beautiful°
2楼-- · 2019-04-16 10:04
grid.Column(
    "dropdown", 
    format: @<span>@Html.DropDownList("Color", (SelectList)item.Colors)</span>
)

Also in your controller make sure you set the value and text properties of your SelectList and instead of:

Colors = new SelectList(colorList)

you should use:

Colors = new SelectList(colorList, "ColorID", "ColorName")

Also it seems a bit wasteful to me to define the same SelectList for all row items especially if they contain the same values. I would refactor your view models a bit:

public class MyViewModel
{
    public IEnumerable<SelectListItem> Colors { get; set; }
    public IEnumerable<PersonViewModel> People { get; set; }
}

public class PersonViewModel
{
    public string Name { get; set; }
    public int Age { get; set; }
    public int SelectedValue { get; set; }
}

and then:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var model = new MyViewModel
        {
            // define the values used to render the dropdown lists
            // for each row
            Colors = new[]
            {
                new SelectListItem { Value = "1", Text = "Green" },
                new SelectListItem { Value = "2", Text = "Red" },
                new SelectListItem { Value = "3", Text = "Yellow" },
            },

            // this is the collection we will be binding the WebGrid to
            People = new[]
            {
                new PersonViewModel { Name = "Foo", Age = 42 },
                new PersonViewModel { Name = "Bar", Age = 1337 },
            }
        };

        return View(model);
    }
}

and in the view:

@model MyViewModel

@{
    var grid = new WebGrid(Model.People);
}

<h2>DropDownList in WebGrid</h2>

@using (Html.BeginForm())
{
    @grid.GetHtml(
        columns: grid.Columns(
            grid.Column("Name"),
            grid.Column("Age"),
            grid.Column(
                "dropdown", 
                format: @<span>@Html.DropDownList("Color", Model.Colors)</span>
            )
        )
    )    
    <p>
        <button>Submit</button>
    </p>
}

UPDATE:

And since I suspect that you are not putting those dropdownlists for painting and fun in your views but you expect the user to select values inside them and when he submits the form you might wish to fetch the selected values, you will need to generate proper names of those dropdown lists so that the default model binder can automatically retrieve the selected values in your POST action. Unfortunately since the WebGrid helper kinda sucks and doesn't allow you to retrieve the current row index, you could use a hack as the Haacked showed in his blog post:

grid.Column(
    "dropdown", 
    format: 
        @<span>
            @{ var index = Guid.NewGuid().ToString(); }
            @Html.Hidden("People.Index", index)
            @Html.DropDownList("People[" + index + "].SelectedValue", Model.Colors)
        </span>
)

Now you could have a POST controller action in which you will fetch the selected value for each row when the form is submitted:

[HttpPost]
public ActionResult Index(MyViewModel model)
{
    // the model variable will contain the People collection
    // automatically bound for each row containing the selected value
    ...
}
查看更多
我想做一个坏孩纸
3楼-- · 2019-04-16 10:16

..make my dropdown list to select a value from the list when it loads.The following works for sure. I have tried it out myself. Any questions keep me posted.

@Html.DropDownList("RejectReason", Model.SalesReasonList.Select(u => new SelectListItem
                {
                    Text = u.Text,
                    Value = u.Value,
                    Selected = u.Value ==@item.RejectReason
                }))
查看更多
登录 后发表回答