首页 > 解决方案 > 如何在 Checkstate 中保存 ASP 复选框状态并在 postba 后检索值

问题描述

我正在开发一个 ASP Webform 应用程序,并在复选框 Viewstate 和 Postback 方面遇到一些挑战。我的应用程序有 2 个网格视图。Gridview 有大约 8 列,其中 3 列有 3 个 TemplateField,每个 TemplateField 都有自己的 ASP 复选框,具有不同的 ID。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>

问题:两个 Gridview 中的每个复选框都会触发事件。示例 Gridview B 事件中的复选框是将选中的行添加到 Gridview A。我设法保存 Gridviews ViewState 并在每次回发或事件后检索它们并成功绑定它们。

我的问题是,Gridview A 中的复选框,我不能或不知道如何将它们的已检查状态保存在 ViewState 中,并在回发后或事件后或页面刷新后恢复它们。在页面刷新或回发后,它们都未选中。

以下是将 Gridview B 中的一行添加到 Gridview A 并从 Gridview A 中删除行的方法

// 创建数据表并保存在 Viewstate 中,我想我也可以在这里将复选框列添加到数据表中,但我不知道如何获取它们的值,因为 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 中移除 Row 的方法

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 所做的那样。任何想法都会非常感激。几个月来,我一直在解决这个问题。

    // Bind ZugeteiltGridview For GetData Method
    private void BindZugeteilteGridviewForGetDataMethod()
    {
        DataTable dt = (DataTable)ViewState["SelectedRecords"];
        gv_ZugeteilteEmailverteiler.DataSource = dt;
        gv_ZugeteilteEmailverteiler.DataBind();
        //CheckAddedRowFromMoglicheEmailverteiler();
    }

标签: c#asp.netcheckboxgridviewviewstate

解决方案


你有AutoPostback=true- 这就是问题所在。不要这样做。

相反,添加一个按钮来执行从 Grid A 到 Grid B 的更改。您应该能够访问复选框值,然后通过在 GridView 行被数据绑定之前循环它们 - 您可能需要一个隐藏字段来存储ID项目的每一行。您应该(如果需要)从数据存储中获取该 ID 的数据,而不是尝试从 GridView 中获取数据。您当然可以尝试,但由于它们是 DataBound 控件,我相信您需要获取单元格的文本。

一旦完成,您就可以重新绑定网格。

确保在循环之前不要对网格 A 进行数据绑定,否则所有复选框都将消失。


推荐阅读