使用 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;
}
我需要用 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;
}