使用 WebControlAdapters 的带有 optgroup 的下拉列表

Dropdownlist with optgroup using WebControlAdapters

我需要用 optgroup 做一个下拉列表。 我找到了很多指南,并且都预见到了 WebControlAdapter 的使用 this is the guide that I'm fllowing

我已将 class 添加到我的 App_Code 文件夹项目中:

 namespace admin.App_Code
 {
   public class DropDownListAdapter :
     System.Web.UI.WebControls.Adapters.WebControlAdapter
   {
    protected override void RenderContents(System.Web.UI.HtmlTextWriter writer)
    {
        // The current control being "adaptered" is available within context from the Control property
        DropDownList dropDownList = (DropDownList)Control;
        ListItemCollection items = dropDownList.Items;

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

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

            int count = group.Items.Count();
            if (count > 0)
            {
                bool flag = false;
                for (int i = 0; i < count; i++)
                {
                    ListItem 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 (this.Page != null)
                    {
                        this.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");
            }
        }
    }

    private Object _ViewState;

    protected override void OnLoad(EventArgs e)
    {
        if (Page.IsPostBack)
        {
            if (_ViewState != null)
            {
                Object[] groups = (Object[])_ViewState;
                DropDownList dropDownList = (DropDownList)Control;
                // Add saved optgroups to ListItems
                for (Int32 i = 0; i < groups.Length; i++)
                {
                    if (groups[i] != null)
                    {
                        dropDownList.Items[i].Attributes["Group"] = groups[i].ToString();
                    }
                }
            }
        }
        base.OnLoad(e);
    }

    protected override void LoadAdapterViewState(object state)
    {
        // Retrieve existing state
        _ViewState = state;
    }

    protected override object SaveAdapterViewState()
    {
        DropDownList dropDownList = (DropDownList)Control;
        Int32 count = dropDownList.Items.Count;
        Object[] values = new Object[count];

        // Retrieve Optgrouping from ListItem 
        for (int i = 0; i < count; i++)
        {
            values[i] = dropDownList.Items[i].Attributes["Group"];
        }
        return values;
    }
   }
}

 public static void loadDDLModelli(ref DropDownList ddl, List<dynamic> 
    objects)
    {
        Int16 cont = 0;
        ddl.Items.Clear();
        System.Web.UI.WebControls.ListItem li;
        String idModello = "";
        String nomeModello = "";
        String nomeBrand = "";
        String oggetto = "";

        List<System.Web.UI.WebControls.ListItem> items = new List<System.Web.UI.WebControls.ListItem>();
        foreach (var item in objects)
        {
            oggetto = item.ToString().Replace("{", "").Replace("}", "");
            idModello = oggetto.Split(',')[0].Split('=')[1].Trim();
            nomeModello = oggetto.Split(',')[1].Split('=')[1].Trim();
            nomeBrand = oggetto.Split(',')[2].Split('=')[1].Trim();
            li = new System.Web.UI.WebControls.ListItem(nomeBrand+" - "+nomeModello, idModello);
            li.Attributes["Group"] = nomeBrand;
            items.Add(li);
            cont++;
        };


        ddl.DataSource = items;
        ddl.DataBind();

        ddl.SelectedIndex = -1;
    }

我已将文件夹 App_Browser 添加到我的项目(不存在)并且我已添加文件 BrowserFile.browser

<browsers>
  <browser refID="Default">
    <controlAdapters>
      <adapter controlType="System.Web.UI.WebControls.DropDownList"
       adapterType="admin.App_Code.DropDownListAdapter" />
    </controlAdapters>
  </browser>
</browsers>

在我的页面 .aspx 中(与我的 class DropDownListAdapter 在同一个文件夹中

 <asp:DropDownList runat="server" ID="ddlModelli" CssClass="form-control multipleSelect"></asp:DropDownList> 

就是这样填的

public static void loadDDLModelli(ref DropDownList ddl, List<dynamic> objects)
    {
        Int16 cont = 0;
        ddl.Items.Clear();
        System.Web.UI.WebControls.ListItem li;
        String idModello = "";
        String nomeModello = "";
        String nomeBrand = "";
        String oggetto = "";

        List<System.Web.UI.WebControls.ListItem> items = new List<System.Web.UI.WebControls.ListItem>();
        foreach (var item in objects)
        {
            oggetto = item.ToString().Replace("{", "").Replace("}", "");
            idModello = oggetto.Split(',')[0].Split('=')[1].Trim();
            nomeModello = oggetto.Split(',')[1].Split('=')[1].Trim();
            nomeBrand = oggetto.Split(',')[2].Split('=')[1].Trim();
            li = new System.Web.UI.WebControls.ListItem(nomeBrand+" - "+nomeModello, idModello);
            li.Attributes["Group"] = nomeBrand;
            items.Add(li);
            cont++;
        };


        ddl.DataSource = items;
        ddl.DataBind();

        ddl.SelectedIndex = -1;
    }

问题是,当我看源代码时,我没有 optgroup 标签,只有 options 标签。

事实上,如果我在方法 RenderContents 的第一行放置一个断点,这不会触发。 我做错了什么?

我解决了这个问题。 问题出在 LoadDDLModelli 方法中。 我没有设置 DataSource 并将 DataBind 绑定到通过引用传递的 Dropdownlist,而是必须单独添加 ItemList(我无法理解其中的区别)

public static void loadDDLModelli(ref DropDownList ddl, List<dynamic> objects)
{
    Int16 cont = 0;
    ddl.Items.Clear();
    System.Web.UI.WebControls.ListItem li;
    String idModello = "";
    String nomeModello = "";
    String nomeBrand = "";
    String oggetto = "";

    List<System.Web.UI.WebControls.ListItem> items = new List<System.Web.UI.WebControls.ListItem>();
    foreach (var item in objects)
    {
        oggetto = item.ToString().Replace("{", "").Replace("}", "");
        idModello = oggetto.Split(',')[0].Split('=')[1].Trim();
        nomeModello = oggetto.Split(',')[1].Split('=')[1].Trim();
        nomeBrand = oggetto.Split(',')[2].Split('=')[1].Trim();
        li = new System.Web.UI.WebControls.ListItem(nomeBrand+" - "+nomeModello, idModello);
        li.Attributes["Group"] = nomeBrand;
        items.Add(li);
        cont++;
    };


    //ddl.DataSource = items;
    //ddl.DataBind();

    foreach(ListItem i in items)
       ddl.Items.Add(i);

    ddl.SelectedIndex = -1;
}