来自多个来源的HTML.DropDownList值?

时间:2010-07-27 17:33:51

标签: asp.net asp.net-mvc vb.net

在ASP.NET MVC中,是否可以从多个数据源填充Html.DropDownList的值列表以及多个手动输入的值?

基本上,我设想它使用OPTGROUP这样的东西进行格式化:

**Group 1**  
Manual Item 1
Manual Item 2
**Group 2**
DS1 Item 1
DS1 Item 2
**Group 3**
DS2 Item 1
DS2 Item 2

我已经考虑过在数据库上使用一个视图并从中获取数据,但是,我并不是真的最狡猾如何使用帮助程序如上所述并将数据从多个来源传递给它。

感谢您提前提供任何帮助。

3 个答案:

答案 0 :(得分:0)

你似乎更容易编写自己的助手。这样做的基本语法是:

// The class can be named anything, but must be static and accessible
public static class HtmlHelperExtensions 
{
    // The method name is what you want to call on Html, 
    // in this case Html.CoolSelectList(arguments...)
    // 
    // The method has to be static, and the first argument should be of the type
    // you're extending (in this case HtmlHelper, which is the type of the
    // Html property on your view). The first argument must be prefixed with the
    // "this" keyword, to indicate it's an extension method.
    // 
    // All the following arguments will be arguments that you supply when calling
    public static string CoolSelectList(this HtmlHelper helper, 
        IEnumerable<IEnumerable<CoolThingThatWeMakeAListOf>> groups)
    {
        // I chose an argument of type IEnumerable<IEnumerable<T>>, since that
        // allows you to create each group of item on its own (i.e. get them from
        // various data sources) and then add all of them to a list of groups
        // that you supply as argument. It is then easy to keep track of which 
        // items belong to which groups, etc.

        // Returned from the extension method is a string you have built, that
        // constitutes the html you want to output on your view. I usually use
        // the TagBuilder class to build the html.

        return "this is what will be on the page";
    }
}

答案 1 :(得分:0)

许多解决方案存在问题。一个是Tomas描述的,另一个是返回PartialView的Controller Action,其中包含用于呈现输入和选项标签的代码,另一个解决方案是让Controller Action使用SelectList填充ViewData或将SelectList作为View / ViewUserControl(部分)的强类型。

答案 2 :(得分:0)

一如既往地从模型开始(实际上从单元测试开始,但这里没有时间):

public class MyModel
{
    public string SelectedItem { get; set; }
    public IEnumerable<SelectListItem> Items { get; set; }
}

然后是控制器:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var items1 = new[] 
        {  
            new { Value = "1", Text = "Manual Item 1" },
            new { Value = "2", Text = "Manual Item 2" },
        };

        // TODO: Go fetch those from your repo1
        var items2 = new[] 
        {  
            new { Value = "3", Text = "DS1 Item 1" },
            new { Value = "4", Text = "DS1 Item 2" },
        };

        // TODO: Go fetch those from your repo2
        var items3 = new[] 
        {  
            new { Value = "5", Text = "DS2 Item 1" },
            new { Value = "6", Text = "DS2 Item 2" },
        };

        var items = items1.Concat(items2).Concat(items3);
        var model = new MyModel
        {
            Items = new SelectList(items, "Value", "Text")
        };
        return View(model);
    }
}

最后是模型的强类型视图:

<%@ Page Language="C#" MasterPageFile="~/Views/Shared/Site.Master" Inherits="System.Web.Mvc.ViewPage<MyApp.Models.MyModel>" %>
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="server">
    <%= Html.DropDownListFor(x => x.SelectedItem, Model.Items) %>
</asp:Content>

您可能会定义一个中间类型,以避免我为简洁起见而使用的匿名类型。

备注:如果您的原始问题是关于使用OPTGROUP,请忽略我的回答并明确您的意图,以便您可以获得更适应的答案。