我有一个页面,用户可以在该页面中选择datalist控件中的不同文档文件。使用on pre-render事件处理程序根据类别对文档进行分类。根据复选框控件(而不是复选框列表)选择文档。到现在为止还挺好。我接下来想要发生的是在每个类别的名称旁边放置一个“全选”复选框,该名称应该只选择该类别下的复选框。这是datalist控件:
<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>
这是OnPreRender代码:
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;
}
}
}
我已经找到了可以在我的代码中运行但没有运气的东西。而且我对这段代码投入太多,现在尝试Checkboxlist控件(不确定这是否会有所帮助)。 有任何想法吗?我以为我可以使用http://www.dotnetcurry.com/ShowArticle.aspx?ID=77代码,但不知道我怎么能做到这一点?如果我可以以某种方式使select all复选框与标签绑定,然后查找所有标签,那么链接的代码可能会有所帮助。 谢谢!
答案 0 :(得分:3)
CatID
和DocID
CheckedChanged
事件: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") %>' />
您还需要在DataList上EnableViewState=true
来维护复选框状态并启用检查/取消选中。
修改强>:
因为你有问题让它运行,这是一个完整的工作样本页面。
以下是aspx所需的控件(注意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>
确保DataList仅为数据绑定if(!IsPostback)
,否则将无法保留复选框选择:
protected void 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
保持不变。
即使您选择单个文档复选框并选择后面的类别复选框,也会按预期工作,这会导致回发。
答案 1 :(得分:0)
我想我可以通过略微修改Tim的代码来实现这一点。几点:我必须为datalist禁用ViewState,否则,check-all触发器不会保持框检查。我不明白为什么。此外,page_load事件中没有ispostback检查,并且datalist在每次加载时绑定。我不是那个'最优'或不是。我还制作了两组Asp:RadioButtons:CheckAll和CheckNone,而不是复选框。无论如何,这是相关的代码:
<asp:DataList ID="DataList1" runat="server" RepeatDirection="Vertical" DataKeyField="docid"
EnableViewState="false" OnItemDataBound="DataList1_ItemDataBound">
<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:RadioButton runat="server" OnCheckedChanged="CheckAllChanged" AutoPostBack="true"
ID="rb_selectall" GroupName="selectallnone" />
| None
<asp:RadioButton runat="server" OnCheckedChanged="CheckAllChangedNone" AutoPostBack="true"
ID="rb_selectnone" GroupName="selectallnone" />
<asp:HiddenField ID="HiddenCatID" runat="server" Value='<%# Eval("CatID") %>' />
<asp:HiddenField ID="HiddenDocID" runat="server" Value='<%# Eval("docid") %>' />
</asp:Label>
</td>
</tr>
<tr runat="server" id="tr_data">
<td>
<asp:CheckBox runat="server" ID="cb_docid" 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>
</asp:DataList>
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;
}
}
protected void CheckAllChanged(Object sender, EventArgs e)
{
RadioButton checkAll = (RadioButton)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"))
.ToList();
foreach (CheckBox docCheckBox in catCheckBoxes)
{
// docCheckBox.Checked = checkAll.Checked;
docCheckBox.Checked = true;
}
}
protected void CheckAllChangedNone(Object sender, EventArgs e)
{
RadioButton checkAll = (RadioButton)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"))
.ToList();
foreach (CheckBox docCheckBox in catCheckBoxes)
{
docCheckBox.Checked = false;
}
}
//订单按钮的部分代码如下;注意使用HiddenField
CheckBox cb = li.FindControl("cb_docid") as CheckBox;
if (cb != null)
{
if (cb.Checked)
{
HiddenField docid = li.FindControl("HiddenDocID") as HiddenField;
string dbcmd = @"Insert Into [order_details] (orderid,docid) Values (" + orderid + "," + docid.Value.ToString() + ")";
答案 2 :(得分:0)
protected void chkAllN_CheckedChanged(object sender, EventArgs e)
{
lblSelectedRecord.InnerText = "0";
/*this Foreach Loop performing for find gridview*/
foreach (DataListItem dst in dstMulEmpSalInsert.Items)
{
GridView grd = (GridView)dst.FindControl("grdMulEmpSalInsert");
CheckBox chk_All = (CheckBox)grd.HeaderRow.FindControl("chkAllN");
if (chk_All.Checked == true)
{
/*this Foreach Loop performing for find gridview Controls*/
foreach (GridViewRow gvr in grd.Rows)
{
CheckBox chk_One = (CheckBox)gvr.FindControl("ChkSendOne");
chk_One.Checked = true;
txt_Salary.ReadOnly = false;
lblSelectedRecord.InnerText = (Convert.ToInt32(lblSelectedRecord.InnerText) + 1).ToString();
}
}
else
{
/*this Foreach Loop performing for find gridview Controls*/
foreach (GridViewRow gvr in grd.Rows)
{
CheckBox chk_One = (CheckBox)gvr.FindControl("ChkSendOne");
chk_One.Checked = false;
}
}
}
}