问题描述
正在开发ASP Webform App,并在复选框Viewstate和Postback方面遇到一些挑战。 我的应用程序有2个Gridviews。 Gridview大约有8列,其中3列具有3个TemplateField,每个TemplateField都有自己的带有不同ID的ASP复选框。 Gridview显示Active Directory中已分配给用户的数据,这些数据将被更新,删除或保持不变。我想使用复选框选中的状态或值进行更新。
请参阅Gridview A的标记
<asp:GridView ID="gv_ZugeteilteEmailverteiler" runat="server" AllowPaging ="true" PageSize="15" CssClass="table table-striped table-bordered" AutoGenerateColumns="false" Width="100%" BorderColor="#DEBA84" BackColor="Silver" HeaderStyle-Height="40px" OnPreRender="gv_ZugeteilteEmailverteiler_PreRender"
HorizontalAlign="Center" CellPadding="0">
<Columns>
<asp:TemplateField HeaderText="Reihe" ItemStyle-Width="200px" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="gruppenname" HeaderText="Gruppenname" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px"/>
<asp:BoundField DataField="standort" HeaderText="Standort" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px"/>
<asp:BoundField DataField="beschreibung" HeaderText="Beschreibung" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px"/>
<asp:BoundField DataField="genehmigt" HeaderText="Genehmigt" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="400px"/>
<asp:BoundField DataField="zielobjekt" HeaderText="ZielObjekt" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px"/>
<asp:BoundField DataField="ACTION_CHECKED" HeaderText="Action_Checked" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px" />
<asp:TemplateField HeaderText="Neu-Hinzufügen" ItemStyle-Width="200px" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="cb_EmailverteilerHinzufuegen" runat="server" AutoPostBack="true" Checked="false" ItemStyle-HorizontalAlign="Center" CssClass="checkboxClass" onclick="CheckBoxCheck(this);" onchange="return javascript:CheckBoxCheck(this);" OnCheckedChanged="cb_EmailverteilerHinzufuegen_CheckedChanged"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Entfernen" ItemStyle-Width="200px" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" >
<ItemTemplate>
<asp:CheckBox ID="cb_EmailverteilerEntfernen" runat="server" AutoPostBack="true" ItemStyle-HorizontalAlign="Center" CssClass="checkboxClass" onclick="CheckBoxCheck(this);" onchange="return javascript:CheckBoxCheck(this);" OnCheckedChanged="cb_EmailverteilerEntfernen_CheckedChanged"/>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Bestätigen" ItemStyle-Width="200px" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="cb_EmailverteilerBestaetigen" runat="server" AutoPostBack="true" ItemStyle-HorizontalAlign="Center" class="checkboxClass" onclick="CheckBoxCheck(this);" onchange="return javascript:CheckBoxCheck(this);" OnCheckedChanged="cb_EmailverteilerBestaetigen_CheckedChanged"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle ForeColor="Black" Font-Bold="True" BackColor="#CCCC00"></HeaderStyle>
</asp:GridView>
Gridview B在“模板”字段中也有大约6列和一个复选框。 Gridview B中的数据是来自AD的目录,可以添加到Gridview A中已显示的用户给定目录的用户列表中。因此,当单击Gridview B中的复选框时,所选或选中的整个行都将添加到Gridview A中。
请参阅Gridview B的标记
<asp:GridView ID="gv_MoeglicheEmailverteiler" runat="server" ClientIDMode="Static"
AutoGenerateColumns="false" BorderColor="#DEBA84" BackColor="Silver" HeaderStyle-Height="40px" OnPreRender="gv_MoeglicheEmailverteiler_PreRender"
HorizontalAlign="Center" CellPadding="3" CssClass="tablesorter">
<Columns>
<asp:TemplateField HeaderText="Reihe" ItemStyle-Width="200px" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<%# Container.DataItemIndex + 1 %>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="gruppenname" HeaderText="Gruppenname" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px"/>
<asp:BoundField DataField="standort" HeaderText="Standort" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px"/>
<asp:BoundField DataField="beschreibung" HeaderText="Beschreibung" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px"/>
<asp:BoundField DataField="genehmigt" HeaderText="Genehmigt" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px"/>
<asp:BoundField DataField="zielobjekt" HeaderText="ZielObjekt" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px"/>
<asp:BoundField DataField="ACTION_CHECKED" HeaderText="Action_Checked" NullDisplayText="n/a" ItemStyle-HorizontalAlign="Center" HeaderStyle-HorizontalAlign="Center" ItemStyle-Width="250px" />
<asp:TemplateField ItemStyle-Width="300px" HeaderText="Action" ItemStyle-HorizontalAlign="Center">
<ItemTemplate>
<asp:CheckBox ID="cb_CheckOneMoglicheverteilerRow" runat="server" ItemStyle-HorizontalAlign="Center" class="checkboxClass" AutoPostBack="true" onclick = "Check_Click(this);" OnCheckedChanged="CheckBox_CheckChanged"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<HeaderStyle ForeColor="Black" Font-Bold="True" BackColor="#CCCC00"></HeaderStyle>
</asp:GridView>
问题:两个Gridviews中的每个复选框都会触发事件。例如,Gridview B事件中的复选框是将选中的行添加到Gridview A中。我设法保存了Gridviews ViewState,并在每次回发或事件后检索它们,并成功绑定它们。
我的问题是,Gridview A中的复选框,我不知道或不知道如何将其checked状态保存在ViewState中,并在回发或事件后或页面刷新后恢复它们。在页面刷新或回发之后,它们都不会被选中。
以下是从Gridview B向Gridview A添加一行并从Gridview A删除行的方法
//创建Datatable并保存在Viewstate中,我想我也可以在此处将checkboxes列添加到datatable中,但是我不知道如何获取它们的值,因为Gridview列的值是从数据库边界域中获取的。
private DataTable CreateDataTable()
{
DataTable dt = new DataTable();
if (ViewState["SelectedRecords"] != null)
{
dt = (DataTable)ViewState["SelectedRecords"];
}
else
{
dt.Columns.Add("gruppenname");
dt.Columns.Add("standort");
dt.Columns.Add("beschreibung");
dt.Columns.Add("genehmigt");
dt.Columns.Add("zielobjekt");
dt.Columns.Add("Action_Checked");
dt.AcceptChanges();
}
return dt;
}
//将行从Gridview A添加到Gridview B的方法
private DataTable AddRow(GridViewRow gvRow,DataTable dt)
{
DataRow[] dr = dt.Select("gruppenname = '" + gvRow.Cells[1].Text + "'");
if (dr.Length <= 0)
{
dt.Rows.Add();
dt.Rows[dt.Rows.Count - 1]["gruppenname"] = gvRow.Cells[1].Text;
dt.Rows[dt.Rows.Count - 1]["standort"] = gvRow.Cells[2].Text;
dt.Rows[dt.Rows.Count - 1]["beschreibung"] = gvRow.Cells[3].Text;
dt.Rows[dt.Rows.Count - 1]["genehmigt"] = gvRow.Cells[4].Text;
dt.Rows[dt.Rows.Count - 1]["zielobjekt"] = gvRow.Cells[5].Text;
dt.Rows[dt.Rows.Count - 1]["Action_Checked"] = gvRow.Cells[6].Text;
dt.AcceptChanges();
}
return dt;
}
//从Gridview A中删除行的方法
private DataTable RemoveRow(GridViewRow gvRow,DataTable dt)
{
DataRow[] dr = dt.Select("gruppenname = '" + gvRow.Cells[1].Text + "'");
if (dr.Length > 0)
{
dt.Rows.Remove(dr[0]);
dt.AcceptChanges();
}
return dt;
}
//现在这就是我称呼他们的方式 //从Gridview Moglicheverteiler中选中的行中获取数据以添加到Gridview Zugeteilte Emailverteiler中的方法
private void GetData()
{
DataTable dt;
if (ViewState["SelectedRecords"] != null)
dt = (DataTable)ViewState["SelectedRecords"];
else
dt = CreateDataTable();
for (int i = 0; i < gv_MoeglicheEmailverteiler.Rows.Count; i++)
{
CheckBox chk = (CheckBox)gv_MoeglicheEmailverteiler.Rows[i].Cells[6].FindControl("cb_CheckOneMoglicheverteilerRow"); string test = gv_MoeglicheEmailverteiler.Rows[i].Cells[1].Text;
if (gv_ZugeteilteEmailverteiler != null && chk.Checked)
{
for (int j = 0; j < gv_ZugeteilteEmailverteiler.Rows.Count; j++)
{
string actionChecked = gv_ZugeteilteEmailverteiler.Rows[j].Cells[6].Text;
if ((chk.Checked && actionChecked == "Bestaetigen")|| (chk.Checked && actionChecked == "Bestaetigt") || (chk.Checked && actionChecked == "TRUE") || (chk.Checked && actionChecked == "FALSE") || (chk.Checked && actionChecked == "Entfernen"))
{
dt = AddRow(gv_MoeglicheEmailverteiler.Rows[i],dt);
dt = AddRow(gv_ZugeteilteEmailverteiler.Rows[j],dt);
}
else if (chk.Checked)
{
dt = AddRow(gv_MoeglicheEmailverteiler.Rows[i],dt);
}
}
}
}
ViewState["SelectedRecords"] = dt;
}
private void SetData()
{
if (ViewState["SelectedRecords"] != null)
{
DataTable dt = (DataTable)ViewState["SelectedRecords"];
for (int i = 0; i < gv_MoeglicheEmailverteiler.Rows.Count; i++)
{
CheckBox chk = (CheckBox)gv_MoeglicheEmailverteiler.Rows[i].Cells[6].FindControl("cb_CheckOneMoglicheverteilerRow");
if (chk != null)
{
DataRow[] dr = dt.Select("gruppenname = '" + gv_MoeglicheEmailverteiler.Rows[i].Cells[1].Text + "'");
chk.Checked = dr.Length > 0;
}
}
}
}
所以简而言之,我想弄清楚如何像将Gridview Columns一样将复选框的值保存到viewstate中。任何想法将不胜感激。我已经在这个问题上待了几个月。
// Bind ZugeteiltGridview For GetData Method
private void BindZugeteilteGridviewForGetDataMethod()
{
DataTable dt = (DataTable)ViewState["SelectedRecords"];
gv_ZugeteilteEmailverteiler.DataSource = dt;
gv_ZugeteilteEmailverteiler.DataBind();
//CheckAddedRowFromMoglicheEmailverteiler();
}
解决方法
您有AutoPostback=true
-这是问题所在。不要这样子。
相反,添加一个按钮以执行从网格A到网格B的更改。您应该能够访问复选框值,然后在数据绑定之前遍历GridView行-您可能需要一个隐藏字段来存储{每行上{1}}项。您比应该(如果需要)从数据存储区获取该ID的数据,而不是尝试从GridView中获取数据。您当然可以尝试,但是由于它们是DataBound控件,我相信您需要获取单元格的文本。
完成后,您可以重新绑定网格。
在遍历网格A之前,请确保未对网格A进行数据绑定,否则所有复选框都将消失。