How to generate and process multiple checklistboxes
Gurus,
I've been searching for a clear example on how I can go about processing multiple, varying categories of items with C# in ASP.NET. The data is similar to the following:
Category1 Heading
Item
Item
Item
Category2 Heading
Item
Item
Item
Category3 Heading
Item
Item
开发者_运维问答 Item
The category names and items come from a SQL database. I imagine I'll need one checkboxlist for each category of items and the number of categories is dynamic and will change over time. Is it possible to create a loop to dynamically build the required checkboxlists and then be able to process them? I read about maybe using a data repeater as well. Any assistance is greatly appreciated.
You could use a repeater or a DataGrid. Occasionally it's easier for me to use a DataGrid and just add rows for each new Category. Do you have any more specifics on what you're looking to do with it?
You could use a DataGrid and for each category add a new row. And within that row add Controls. A less savvy way would be to use a PlaceHolder on the page and just add controls to that. But I would definitely suggest a DataGrid or looking into the Repeater.
You could try something like this...
Your business object. You may use this as a model you can transform from your 'real' business object or use your business object directly
public class BusinessObject
{
public string Category { get; set; } //Your category
public int ID { get; set; } //Point of data entry and will be return on post
public string Name { get; set; } //A friendly name for your users
}
Your aspx markup. I'm using a repeater for the categories which just has a CheckBoxList
in it which will have the actual items. This can be expanded and styled quite a bit.
<asp:Repeater ID="myRepeater" runat="server">
<ItemTemplate>
<asp:CheckBoxList ID="checkboxlist"
runat="server"
DataTextField="Name"
DataValueField="ID" />
</ItemTemplate>
</asp:Repeater>
A Place to get your business objects from: Here I just have a member on my codebehind. You should grab this data from your business layer/tier.
List<BusinessObject> MyBusinessObjects = new List<BusinessObject>();
And your code behind
protected void Page_Load(object sender, EventArgs e)
{
//Wire up the event to handle when items are bound to the repeater
this.myRepeater.ItemDataBound += new RepeaterItemEventHandler(myRepeater_ItemDataBound);
//Now actually bind the categories to the repeater
this.myRepeater.DataSource = GetCategories(MyBusinessObjects);
this.myRepeater.DataBind();
}
void myRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
//Don't process items that are not item, or alternating item
if (!(e.Item.ItemType == ListItemType.AlternatingItem || e.Item.ItemType == ListItemType.Item)) return;
//Grab a reference to the checkboxlist in our repeater
CheckBoxList checkboxlist = (CheckBoxList)e.Item.FindControl("checkboxlist");
//Now put our business objects of that category in it
checkboxlist.DataSource = GetItemsFromCategory(MyBusinessObjects, (string)e.Item.DataItem);
checkboxlist.DataBind();
}
//Helper to grab categories.
private IEnumerable<string> GetCategories(IEnumerable<BusinessObject> items)
{
return (from i in items
select i.Category).Distinct();
}
//Helper to grab the items in categories.
private IEnumerable<BusinessObject> GetItemsFromCategory(IEnumerable<BusinessObject> items, string category)
{
return (from i in items
where i.Category == category
select i);
}
If you don't know in advance how many items there could be, then you need a display that will not break. The best way to achieve this is by using a ListView with a GroupTemplate:
http://forums.asp.net/t/1364813.aspx/1
just imagine that this is your data structure. To do without repeaters.
var list = new Dictionary<string, List<string>> { {"Name1", new List {"item1", "item2", "item3"}}, {"Name2", new List {"item1", "item2", "item3"}}, {"Name3", new List {"item1", "item2", "item3"}}, {"Name4", new List {"item1", "item2", "item3"}}, {"Name5", new List {"item1", "item2", "item3"}} }; foreach (var category in list) { var checkBoxList = new CheckBoxList { Text = category.Key }; foreach (var value in category.Value) { var listItem = new ListItem(value); checkBoxList.Items.Add(listItem); } }
Thanks again to everyone for the help. We ended up changing the requirements and a single checkboxlist will now suffice. I think the dynamic addition of the checkboxlists to a placeholder would have worked though.
精彩评论