2013-04-23 133 views
27

我有一個要求在ASP.NET下拉式服務器控件中分組下拉列表選項。你有什麼想法如何解決這個問題?我是ASP.NET新手。如何在ASP.NET下拉列表中添加選項組?

My requirement.

+3

有趣的是,你發佈的打印內容來自一篇文章,解釋如何在asp.net下拉列表控件中實現這一點。它不工作嗎? – 2013-04-23 11:13:57

+2

該網站從你的圖片中解釋了http://ignatu.co.uk/articles/Adding_groups_to_the_ASPNET_DropDownList_control/ – keyboardP 2013-04-23 11:14:31

+2

看到這篇文章[DropDownList中的組選項](http://weblogs.asp.net/alaaalnajjar/archive/2009 /11/16/group-options-in-dropdownlist.aspx)和這[下拉列表控件與 s爲asp.net(webforms)?](http://stackoverflow.com/questions/130020/dropdownlist-control-with -optgroups-for-asp-net-webforms) – 2013-04-23 11:15:15

回答

33

看看這篇文章,我也曾經有過需要組下拉列表。 。 。

ASP.NET DropDownList with OptionGroup support

用法:

protected void Page_Load(object sender, EventArgs e) 
{ 

       ListItem item1 = new ListItem("Camel", "1"); 
       item1.Attributes["OptionGroup"] = "Mammals"; 

       ListItem item2 = new ListItem("Lion", "2"); 
       item2.Attributes["OptionGroup"] = "Mammals"; 

       ListItem item3 = new ListItem("Whale", "3"); 
       item3.Attributes["OptionGroup"] = "Mammals"; 

       ListItem item4 = new ListItem("Walrus", "4"); 
       item4.Attributes["OptionGroup"] = "Mammals"; 

       ListItem item5 = new ListItem("Velociraptor", "5"); 
       item5.Attributes["OptionGroup"] = "Dinosaurs"; 

       ListItem item6 = new ListItem("Allosaurus", "6"); 
       item6.Attributes["OptionGroup"] = "Dinosaurs"; 

       ListItem item7 = new ListItem("Triceratops", "7"); 
       item7.Attributes["OptionGroup"] = "Dinosaurs"; 

       ListItem item8 = new ListItem("Stegosaurus", "8"); 
       item8.Attributes["OptionGroup"] = "Dinosaurs"; 

       ListItem item9 = new ListItem("Tyrannosaurus", "9"); 
       item9.Attributes["OptionGroup"] = "Dinosaurs"; 


       ddlItems.Items.Add(item1); 
       ddlItems.Items.Add(item2); 
       ddlItems.Items.Add(item3); 
       ddlItems.Items.Add(item4); 
       ddlItems.Items.Add(item5); 
       ddlItems.Items.Add(item6); 
       ddlItems.Items.Add(item7); 
       ddlItems.Items.Add(item8); 
       ddlItems.Items.Add(item9); 

      } 
+0

有關此方法的一個注意事項是,它在工作時必須實現自定義視圖狀態邏輯以保存屬性並在回發後將其恢復。 [如何保持屬性](https://stackoverflow.com/questions/1313447/listitems-attributes-in-a-dropdownlist-are-lost-on-postback) – Aaron 2017-07-24 04:07:00

30

我真的很喜歡這個客戶端解決方案(不需要自定義的DropDownList,而是用了jQuery):

後端

private void _addSelectItem(DropDownList list, string title, string value, string group = null) { 
    ListItem item = new ListItem(title, value); 
    if (!String.IsNullOrEmpty(group)) 
    { 
     item.Attributes["data-category"] = group; 
    } 
    list.Items.Add(item); 
} 

... 
_addSelectItem(dropDown, "Option 1", "1"); 
_addSelectItem(dropDown, "Option 2", "2", "Category"); 
_addSelectItem(dropDown, "Option 3", "3", "Category"); 
... 

客戶

var groups = {}; 
$("select option[data-category]").each(function() { 
    groups[$.trim($(this).attr("data-category"))] = true; 
}); 
$.each(groups, function (c) { 
    $("select option[data-category='"+c+"']").wrapAll('<optgroup label="' + c + '">'); 
}); 
+0

這是很好的破解:) – Thomas 2014-07-28 14:05:11

+0

謝謝,我到就像您提供的客戶端修改一樣! – 2015-07-27 13:39:00

+0

太棒了!此外,爲了保存這些屬性,由於PostBack的問題,而不創建ServerControl或複雜的:http://stackoverflow.com/a/33657968/2093328 – 2015-11-11 19:08:58

2
----- in .cs ----- 

List<SelectListItem> sl = new List<SelectListItem>(); 

sl.Add(new SelectListItem() { Text = "My text", Value = "1", Group = new SelectListGroup() { Name = "First Group" } }); 

sl.Add(new SelectListItem() { Text = "My text 2", Value = "2", Group = new SelectListGroup() { Name = "First Group" } }); 

var sl1 = new SelectList(sl,"Value","Text","Group.Name",-1); 

ViewData["MyList"] = sl1; 


----- in .cshtml ----- 
Html.DropDownList("My List", ViewData["MyList"] as SelectList, 
         "-- No Preference --", 
         new { 
          @class = "ui-widget ui-corner-all square_corners searchPageDropdown" 
         })) 
4

這是舊的,但因爲我最近使用公認的答案,我想分享我的經驗它。雖然它確實提供了正確的標記,但它對我造成了問題,特別是每當我嘗試使用任何下拉列表提交表單時,我都會遇到可怕的「無效回發或回調參數」錯誤。 Google瘋狂搜索後,我遇到了this article,然後鏈接到this blog post。我結束了使用的代碼是這樣的:

public class DropDownListAdapter : System.Web.UI.WebControls.Adapters.WebControlAdapter { 
    protected override void RenderContents(HtmlTextWriter writer) { 

     var dropDownList = (DropDownList)Control; 
     var items = dropDownList.Items; 

     var groups = (from p in items.OfType<ListItem>() 
         group p by p.Attributes["Group"] into g 
         select new { Label = g.Key, Items = g.ToList() }); 

     foreach (var group in groups) 
     { 
      if (!String.IsNullOrEmpty(group.Label)) 
      { 
       writer.WriteBeginTag("optgroup"); 
       writer.WriteAttribute("label", group.Label); 
       writer.Write(">"); 
      } 

      var count = group.Items.Count(); 
      if (count > 0) 
      { 
       var flag = false; 
       for (var i = 0; i < count; i++) 
       { 
        var item = group.Items[i]; 

        writer.WriteBeginTag("option"); 
        if (item.Selected) 
        { 
         if (flag) 
         { 
          throw new HttpException("Multiple selected items not allowed"); 
         } 
         flag = true; 

         writer.WriteAttribute("selected", "selected"); 
        } 

        if (!item.Enabled) 
        { 
         writer.WriteAttribute("disabled", "true"); 
        } 

        writer.WriteAttribute("value", item.Value, true); 

        if (Page != null) 
        { 
         Page.ClientScript.RegisterForEventValidation(dropDownList.UniqueID, item.Value); 
        } 
        writer.Write('>'); 
        HttpUtility.HtmlEncode(item.Text, writer); 
        writer.WriteEndTag("option"); 
        writer.WriteLine(); 
       } 
      } 
      if (!String.IsNullOrEmpty(group.Label)) 
      { 
       writer.WriteEndTag("optgroup"); 
      } 
     } 
    } 
} 

這裏使用的listItems中在設計頁面中創建,而不是代碼隱藏頁,像這樣:

<asp:ListItem Value="apple" Text="Apple" Group="Fruit"></asp:ListItem> 
<asp:ListItem Value="banana" Text="Banana" Group="Fruit"></asp:ListItem> 
<asp:ListItem Value="asparagus" Text="Asparagus" Group="Vegetable"></asp:ListItem> 
<asp:ListItem Value="eggs" Text="Eggs" Group="Dairy"></asp:ListItem> 

這產生了相同的標記作爲接受的答案在這裏,但這並沒有給我回發錯誤。我希望這可以拯救一些人的悲傷。

+0

我是ASP.NET的新手,無法找出放置下拉列表適配器代碼的位置。如果我將它放入我的代碼中,那麼「group」不是listitem的有效屬性。下拉列表適配器是否必須作爲單獨的項目添加,如果是的話? – 2017-03-10 16:45:32

+1

哎呀!我很抱歉,我直到現在纔看到這一點。我的歉意,@ brent。這可能不會幫助你,但我會盡力提供幫助。 DropDownListAdapter類可以去任何你認爲有意義的地方。在你的類中包含下拉列表,把一個using語句放在類的保存位置。在Page_PreInit中,我將此語句放在Context.Request.Browser.Adapters.Add(typeof(DropDownList).FullName,typeof(DropDownListAdapter).FullName);'中。你得到的警告仍然會在那裏,但它應該仍然有效。 – dougF 2017-05-31 15:33:06

2

1)從here添加下拉列表適配器類到您的項目

2)App_Browsers文件夾添加到您的項目(右鍵單擊項目=>添加=>添加ASP.NET文件夾=> App_Browsers文件)

3)將瀏覽器文件添加到App_Browsers頁面,並在瀏覽器標籤內添加以下代碼。

<browser refID="WebKit"> <controlAdapters> <adapter controlType="System.Web.UI.WebControls.DropDownList" adapterType="YourAdapterClasse'sNameSPace.DropDownListAdapter" /> </controlAdapters> </browser>

REFID =的WebKit支持Chrome和Safari瀏覽器

4)然後你就可以將項目添加到您的下拉列表 列表項物品1 =新的ListItem( 「史密斯街」, 「1」); item1。屬性[「OptionGroup」] =「達爾文」;

  ListItem item2 = new ListItem("Mitchel Street", "1"); 
      item2.Attributes["OptionGroup"] = "Darwin"; 

      ListItem item3 = new ListItem("Hunter Street", "2"); 
      item3.Attributes["OptionGroup"] = "Sydney"; 

      ListItem item4 = new ListItem("BroadwaY", "4"); 
      item4.Attributes["OptionGroup"] = "Sydney"; 

      venuedropdown.Items.Add(item1); 
      venuedropdown.Items.Add(item2); 
      venuedropdown.Items.Add(item3); 
      venuedropdown.Items.Add(item4); 
0

我用這個方法,避免了ViewBag和ViewData的:

查看模型:

public class PageViewModel 
{ 
    public int SelectedDropdownItem { get; set; } 
    public IEnumerable<SelectListItem> DropdownList { get; set; } 
} 

例實體模型(在這個例子中):

public class Users 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public bool IsAdministrator { get; set; } 
    public bool IsDefault { get; set; } 
} 

控制器:

// Get list for the dropdown (this uses db values) 
var userList = db.Users.ToList(); 

// Define the Groups 
var group1 = new SelectListGroup { Name = "Administrators" }; 
var group2 = new SelectListGroup { Name = "Users" }; 

// Note - the -1 is needed at the end of this - pre-selected value is determined further down 
// Note .OrderBy() determines the order in which the groups are displayed in the dropdown 
var dropdownList = new SelectList(userList.Select(item => new SelectListItem 
{ 
    Text = item.Name, 
    Value = item.Id, 
    // Assign the Group to the item by some appropriate selection method 
    Group = item.IsAdministrator ? group1 : group2 
}).OrderBy(a => a.Group.Name).ToList(), "Value", "Text", "Group.Name", -1); 

// Assign values to ViewModel 
var viewModel = new PageViewModel 
{ 
    // Assign the pre-selected dropdown value by appropriate selction method (if needed) 
    SelectedDropdownItem = userList.FirstOrDefault(a => a.IsDefault).Id, 
    DropdownList = dropdownList 
}; 

查看:

<!-- If needed, change 'null' to "Please select item" --> 
@Html.DropDownListFor(a => a.SelectedDropdownItem, Model.DropdownList, null, new { @class = "some-class" }) 

希望這可以幫助別人,以避免發生在我身上 - 花找到一個強類型的方法了太多的時間。

0

mhu's excellent solution的客戶端的這個小改進也適用於有多個選擇標記的情況。

隨着他的版本,實際上,每一個選擇標記都充斥着每一個選擇標籤

的每個選項標籤的一個副本(在這個例子中,.select2是通用於所有選擇標籤類)

function filterUserGroups() 
{ 

    var groups = {}; 
    $("select option[data-category]").each(function() { 
     var sGroup = $.trim($(this).attr("data-category")); 
     groups[sGroup] = true; 
    }); 
    $.each(groups, function (c) { 

     $(".select2").each(function() { 

      $(this).find("option[data-category='" + c + "']").wrapAll('<optgroup label="' + c + '">'); 

     }) 

    }); 

} 
0

下面是我做什麼,用jQuery只,沒有服務器端更改:

/* Add Option Groups to Note Dropdown */ 
var $select = $('#<%= DropDownListIDHere.ClientID %>'); 
var optGroup; 
$('#<%= DropDownListIDHere.ClientID %> option').each(function() { 
    if ($(this).val() == '<') { 
     /* Opener */ 
     optGroup = $('<optGroup>').attr('label', $(this).text()); 
    } else if ($(this).val() == '>') { 
     /* Closer */ 
     $('</optGroup>').appendTo(optGroup); 
     optGroup.appendTo($select); 
     optGroup = null; 
    } else { 
     /* Normal Item */ 
     if (optGroup) { 
      $('<option>' + $(this).text() + '</option>').attr('value', $(this).val()).appendTo(optGroup); 
     } else { 
      $('<option>' + $(this).text() + '</option>').attr('value', $(this).val()).appendTo($select); 
     } 
    } 
    $(this).remove(); 
}); 

然後,你只需要添加特定的項目,如開啓和關閉子與價值<和>像這樣:

<asp:ListItem Text="Group 1" Value="<" /> 
<asp:ListItem Text="Thing 1" Value="1111" /> 
<asp:ListItem Text="Thing 2" Value="2222" /> 
<asp:ListItem Text="Thing 3" Value="3333" /> 
<asp:ListItem Text="Group 1" Value=">" /> 

超級簡單,不需要新的控制,只針對你想改變選擇,並且不要求每一個項目是在OPTGROUP。

相關問題