asp.net datalist选择每个类别的所有复选框 [英] asp.net datalist select all checkboxes per category
问题描述
我有一个页面,用户可以在datalist控件中选择不同的文档文件。文档根据类别使用预呈现事件处理程序进行分类。文档基于复选框控件(而不是Checkboxlist)进行选择。到现在为止还挺好。我想要发生的是,在每个类别的名称旁边放置一个全选复选框应该只选择该类别下的复选框。这里是数据控制:
< asp:DataList ID =DataList1runat =serverRepeatDirection =Vertical OnPreRender =DataList1_PreRenderDataKeyField =docidEnableViewState =false>
< ItemTemplate>
< table cellpadding =0cellspacing =0id =tbl_data>
< tr>
< td>
< asp:Label ID =lblHeaderrunat =serverFont-Bold =TrueFont-Underline =True>< / asp:Label>
< asp:Label runat =serverid =lbl_cb_allvisible =false>全选< input runat =serverid =cb_selectalltype =checkboxvalue = ;%#Eval(catid)%>'/> < / asp:Label>
< / td>
< / tr>
< tr runat =serverid =tr_data>
< td>
< asp:Label ID =lbl_Categorynamerunat =serverText ='<%#Eval(categoryname)%>'Visible =false/> <! - 隐藏此;仅用于代码背后 - >
< input runat =serverid =cb_docidtype =checkboxvalue ='<%#Eval(docid)%>'/>
< asp:Hyperlink ID =hpl_docfileencrText ='<%#Eval(docfileencr)%>'NavigateUrl ='<%#〜/ PDFEncr /+ DataBinder.Eval .DataItem,docfileencr)%>'Target =_ blankrunat =server/>
< br />
< / td>
< / tr>
< / table>
< / ItemTemplate>
,这里是OnPreRender代码:
protected void DataList1_PreRender(object sender,EventArgs e)
{
string strTempLabelCategory =;
foreach(DataList1.Items中的DataListItem项)
{
标签lbl_categoryname = item.FindControl(lbl_categoryname)as Label;
if(strTempLabelCategory.ToUpper()!= lbl_Categoryname.Text.ToString()。ToUpper())
{
strTempLabelCategory = lbl_categoryname.Text.ToString ).ToUpper();
标签lblHeader = item.FindControl(lblHeader)as Label;
lblHeader.Text = strTempLabelCategory.ToUpper();
标签lbltempdiv = item.FindControl(lbl_cb_all)as Label;
lbltempdiv.Visible = true;
}
}
}
可以在我的代码中工作,但没有运气。和我太投资这个代码,现在尝试Checkboxlist控制(不知道如果这将帮助反正)。
任何想法?我以为我可以使用: http://www.dotnetcurry.com/ShowArticle.aspx?ID = 77 代码,但不知道我该如何使这项工作?如果我能以某种方式使选择所有复选框绑定到一个标签,然后寻找所有标签,然后可能是链接的代码将有所帮助。
- 使用HiddenFields存储
CatID
和和
DocID
- 使用ASP.NET CheckBoxes而不是HTML-输入
- 处理所有复选框
CheckedChanged
事件:
protected void CheckAllChanged(Object sender,EventArgs e)
{
CheckBox checkAll =
DataListItem item =(DataListItem)checkAll.NamingContainer;
HiddenField HiddenCatID =(HiddenField)item.FindControl(HiddenCatID);
var catCheckBoxes = DataList1.Items.Cast< DataListItem>()
.Where(li =>((HiddenField)li.FindControl(HiddenCatID))Value == HiddenCatID.Value)
.Select(li => li.FindControl(cb_docid));
foreach(catCheckBoxes中的CheckBox docCheckBox)
{
docCheckBox.Checked = checkAll.Checked;
}
}
在aspx上:
< asp:CheckBox runat =serverOnCheckedChanged =CheckAllChangedAutoPostBack =trueid =cb_selectall/&
< asp:HiddenField ID =HiddenCatIDrunat =serverValue ='<%#Eval(CatID)%>'/>
< asp:HiddenField ID =HiddenDocIDrunat =serverValue ='<%#Eval(DocID)%>'/>
您还需要 EnableViewState = true
因为你有问题需要运行,所以这里有一个完整的工作示例页面。
(note fe < tr runat =serverid =tr_category>)
:
< ItemTemplate>
< table cellpadding =0cellspacing =0id =tbl_data>
< tr runat =serverid =tr_category>
< td>
< asp:Label ID =lblHeaderrunat =serverFont-Bold =TrueText ='<%#Eval(categoryname)%> >< / asp:Label>
< asp:Label runat =serverID =lbl_cb_all>全选
< asp:CheckBox runat =serverOnCheckedChanged =CheckAllChangedAutoPostBack =trueid = cb_selectall/>
< / asp:Label>
< / td>
< / tr>
< tr runat =serverid =tr_data>
< td>
< asp:HiddenField ID =HiddenCatIDrunat =serverValue ='<%#Eval(CatID)%>'/>
< asp:CheckBox runat =serverid =cb_docid/>
< asp:HyperLink ID =hpl_docfileencrText ='<%#Eval(docfileencr)%>'NavigateUrl ='<%#〜/ PDFEncr /+ DataBinder.Eval .DataItem,docfileencr)%>'
Target =_ blankrunat =server/>
< br />
< / td>
< / tr>
< / table>
< / ItemTemplate>
-
确保DataList只有数据绑定
if(!IsPostback)
,否则将不会保留复选框选择:Page_Load(object sender,EventArgs e)
{
if(!IsPostBack)BindDataList();
}
-
我使用
ItemDataBound
而不是
PreRender
,这对于正确重新加载ViewState非常重要。我还简化了所有:protected void DataList1_ItemDataBound(Object sender,DataListItemEventArgs e)
{
if(e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem)
{
var row =(DataRowView)e.Item.DataItem;
var view = row.DataView;
var lastRow = e.Item.ItemIndex == 0? null:view [e.Item.ItemIndex-1];
var tr_category =(System.Web.UI.HtmlControls.HtmlTableRow)e.Item.FindControl(tr_category);
var sameCategory = lastRow!= null&& (int)row [catid] ==(int)lastRow [catid];
tr_category.Visible =!sameCategory;
}
}
-
CheckAllChanged
即使您选择单个文档,然后选择一个category-checkbox,这会导致回发。
I have a page where users can select different documents files in a datalist control. The documents are categorized based on categories using the on pre-render event handler. Documents are selected based on Checkbox controls (not Checkboxlist). So far so good. What I want to happen next is to put a 'Select All' checkbox beside each Category's name which should select only checkboxes under that category. Here is the datalist control:
<asp:DataList ID="DataList1" runat="server" RepeatDirection="Vertical" OnPreRender="DataList1_PreRender" DataKeyField="docid" EnableViewState="false">
<ItemTemplate>
<table cellpadding="0" cellspacing="0" id="tbl_data">
<tr>
<td>
<asp:Label ID="lblHeader" runat="server" Font-Bold="True" Font-Underline="True"></asp:Label>
<asp:Label runat="server" id="lbl_cb_all" visible="false">Select All <input runat="server" id="cb_selectall" type="checkbox" value='<%# Eval("catid") %>' /> </asp:Label>
</td>
</tr>
<tr runat="server" id="tr_data">
<td>
<asp:Label ID="lbl_categoryname" runat="server" Text='<%# Eval("categoryname") %>' Visible="false" /> <!-- Hide this; only used in Code Behind -->
<input runat="server" id="cb_docid" type="checkbox" value='<%# Eval("docid") %>' />
<asp:Hyperlink ID="hpl_docfileencr" Text='<%# Eval("docfileencr") %>' NavigateUrl='<%# "~/PDFEncr/" + DataBinder.Eval(Container.DataItem, "docfileencr") %>' Target="_blank" runat="server" />
<br />
</td>
</tr>
</table>
</ItemTemplate>
and here is the OnPreRender code:
protected void DataList1_PreRender(object sender, EventArgs e)
{
string strTempLabelCategory = "";
foreach (DataListItem item in DataList1.Items)
{
Label lbl_categoryname = item.FindControl("lbl_categoryname") as Label;
if (strTempLabelCategory.ToUpper() != lbl_categoryname.Text.ToString().ToUpper())
{
strTempLabelCategory = lbl_categoryname.Text.ToString().ToUpper();
Label lblHeader = item.FindControl("lblHeader") as Label;
lblHeader.Text = strTempLabelCategory.ToUpper();
Label lbltempdiv = item.FindControl("lbl_cb_all") as Label;
lbltempdiv.Visible = true;
}
}
}
I have looked for something which can work within my code but no luck. And I am too invested in this code to now try Checkboxlist control (not sure if that would help anyway). Any ideas? I thought I could use: http://www.dotnetcurry.com/ShowArticle.aspx?ID=77 code but not sure how I can make that work? If I can somehow make the select all checkbox tie to a tag and then look for all tag then may be the link's code would help. Thanks!
- Use HiddenFields to store
CatID
andDocID
- Use ASP.NET CheckBoxes instead of HTML-Inputs for both
- Handle the Check-All Checkbox'
CheckedChanged
event:
protected void CheckAllChanged(Object sender, EventArgs e)
{
CheckBox checkAll = (CheckBox)sender;
DataListItem item = (DataListItem)checkAll.NamingContainer;
HiddenField HiddenCatID = (HiddenField)item.FindControl("HiddenCatID");
var catCheckBoxes = DataList1.Items.Cast<DataListItem>()
.Where(li => ((HiddenField)li.FindControl("HiddenCatID")).Value == HiddenCatID.Value)
.Select(li => li.FindControl("cb_docid"));
foreach (CheckBox docCheckBox in catCheckBoxes)
{
docCheckBox.Checked = checkAll.Checked;
}
}
on aspx:
<asp:CheckBox runat="server" OnCheckedChanged="CheckAllChanged" AutoPostBack="true" id="cb_selectall" />
<asp:HiddenField ID="HiddenCatID" runat="server" Value='<%# Eval("CatID") %>' />
<asp:HiddenField ID="HiddenDocID" runat="server" Value='<%# Eval("DocID") %>' />
You also need to EnableViewState=true
on the DataList to maintain checkbox state and enable checking/unchecking.
Edit:
Because you have problems to get it running, here's a complete working sample page.
Here are the required controls on aspx(note f.e. <tr runat="server" id="tr_category">)
:
<ItemTemplate>
<table cellpadding="0" cellspacing="0" id="tbl_data">
<tr runat="server" id="tr_category">
<td>
<asp:Label ID="lblHeader" runat="server" Font-Bold="True" Text='<%# Eval("categoryname") %>' Font-Underline="True"></asp:Label>
<asp:Label runat="server" ID="lbl_cb_all">Select All
<asp:CheckBox runat="server" OnCheckedChanged="CheckAllChanged" AutoPostBack="true" id="cb_selectall" />
</asp:Label>
</td>
</tr>
<tr runat="server" id="tr_data">
<td>
<asp:HiddenField ID="HiddenCatID" runat="server" Value='<%# Eval("CatID") %>' />
<asp:CheckBox runat="server" id="cb_docid" />
<asp:HyperLink ID="hpl_docfileencr" Text='<%# Eval("docfileencr") %>' NavigateUrl='<%# "~/PDFEncr/" + DataBinder.Eval(Container.DataItem, "docfileencr") %>'
Target="_blank" runat="server" />
<br />
</td>
</tr>
</table>
</ItemTemplate>
Ensure that the DataList is databound only
if(!IsPostback)
, otherwise the checkbox selection will not be maintained:protected void Page_Load(object sender, EventArgs e) { if (!IsPostBack) BindDataList(); }
I'm using
ItemDataBound
instead ofPreRender
which is important for the ViewState to be reloaded correctly. I've also simplified all:protected void DataList1_ItemDataBound(Object sender, DataListItemEventArgs e) { if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType==ListItemType.AlternatingItem) { var row = (DataRowView)e.Item.DataItem; var view = row.DataView; var lastRow = e.Item.ItemIndex == 0 ? null : view[e.Item.ItemIndex-1]; var tr_category = (System.Web.UI.HtmlControls.HtmlTableRow)e.Item.FindControl("tr_category"); var sameCategory = lastRow != null && (int)row["catid"] == (int)lastRow["catid"]; tr_category.Visible = !sameCategory; } }
The
CheckAllChanged
remains unchanged.
This works as expected even if you select a single document-checkbox and select a category-checkbox afterwards which causes a postback.
这篇关于asp.net datalist选择每个类别的所有复选框的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!