6

我目前对填充 DropDownListFor() 对象的方式不满意。我试图找到尽可能通用的填充 IEnumerable 的方法。这就是我到目前为止所拥有的。

帮手:

public static List<SelectListItem> ToSelectList(IDictionary<string,string> dictionaryItems, string selectedValue, string noSelection, bool search = false)
    {
        List<SelectListItem> items = new List<SelectListItem>();

        if (search)
        {
            items.Add(new SelectListItem { Selected = true, Value = "-1", Text = string.Format("-- {0} --", noSelection) });
        }

        foreach (var item in dictionaryItems)
        {
            items.Add(new SelectListItem
            {
                Text = item.Key,
                Value = item.Value,
                Selected = selectedValue == item.Value ? true : false
            });
        }

        return items
            .OrderBy(l => l.Text)
            .ToList();
    }

控制器:

[HttpGet]
    public ActionResult Index()
    {
        var model = new CreateModel();

        var parentOrganisations = _orgs.FindBy(o => o.OwningOrganisationID == Globals.OrganisationID || o.ID == Globals.OrganisationID)
            .OrderBy(o => o.OrganisationName);

        Dictionary<string, string> items = new Dictionary<string, string>();

        foreach (var item in parentOrganisations)
        {
            items.Add(item.OrganisationName, item.ID.ToString());
        }

        model.Organisations = SelectLists.ToSelectList(items, "-1", "-- None -- ", true);

        return View(model);
    }

看法:

<div class="control-group">
        <label class="control-label">Parent Organisation</label>
        <div class="controls">
            @Html.DropDownListFor(m => m.ParentOrganisationID, Model.Organisations, new { @class = "input-xlarge"})
            <p class="help-block">Select a parent organisation to create a branch</p>
        </div>
    </div>

控制器中似乎有很多重复的代码。它需要一个通用列表,将值和文本添加到字典中,然后将其用作帮助器的输入,该帮助器构建选择列表以作为模型的一部分发送。

有没有人有更好的方法来实现这一目标?我讨厌我的控制器膨胀,当我在一个表单上获得几个下拉菜单时,这正是在这种情况下会发生的事情。

谢谢,

编辑 - 感谢 Kenneth 的辅助方法,我现在将整个事情合并到控制器中的一个调用中:

            model.Organisations = _orgs.FindBy(o => o.OwningOrganisationID == Globals.OrganisationID || o.ID == Globals.OrganisationID)
            .OrderBy(o => o.OrganisationName)
            .ToList()
            .ToSelectList(org => org.OrganisationName, org => org.ID.ToString(), "-1", "None", true);
4

2 回答 2

8

您可以提供获取键和值的回调,然后使用它们。除此之外,您可以将其创建为扩展方法:

扩展方法:

public static List<SelectListItem> ToSelectList<T>(this List<T> Items, Func<T, string> getKey, Func<T, string> getValue, string selectedValue, string noSelection, bool search = false)
    {
        List<SelectListItem> items = new List<SelectListItem>();

        if (search)
        {
            items.Add(new SelectListItem { Selected = true, Value = "-1", Text = string.Format("-- {0} --", noSelection) });
        }

        foreach (var item in Items)
        {
            items.Add(new SelectListItem
            {
                Text = getKey(item),
                Value = getValue(item),
                Selected = selectedValue == getValue(item) ? true : false
            });
        }

        return items
            .OrderBy(l => l.Text)
            .ToList();
    }

用法:

List<Org>() parentOrganisations = // fetch here
model.Organisations = parentOrganisations.ToSelectList(org => org.ID.ToString(), 
                                                       org => org.OrganisationName,
                                                       "-1", 
                                                       "-- None -- ", 
                                                       true);

注意:我在 SO-editor 中输入了这个,所以你可能会遇到一些语法错误(尽管它们应该很容易解决)。

于 2013-06-04T10:35:47.773 回答
1

您只能在控制器中这样做:-

List<SelectListItem> dropdownItems = parentOrganisations
    .Select(item => new SelectListItem
    {
        Value = item.ID.ToString(),
        Text = item.OrganisationName,
        Selected = "-1" == item.ID.ToString() ? true : false
    })
    .ToList();
于 2013-06-04T10:36:26.417 回答