【问题标题】:Postback resets the selectedValue of DropdownList inside GridViewPostback 重置 GridView 内 DropdownList 的 selectedValue
【发布时间】:2013-08-14 18:41:10
【问题描述】:

我的 gridview 有 2 列 - DropDownList 和 TextBox。 DDL 由数据表进行数据绑定。 DDL 的 SelectedIndex 更改将填充其文本框并添加新行。所有这些都可以正常工作,但是当添加新行时,先前行的 DDL 的选定值会重置为 0 索引。尽管文本框值保持不变。添加新行时如何保留 DDL 选择的值。

例如。如果我从第 1 行的下拉列表中选择“abc”,它会填充其文本字段并添加一个新行。但是随着回发的发生,abc 不会在第 1 行 ddl 中保持选中状态:

 登录电话

1 123456789

2

ASPX:

<asp:GridView ID="gvCommissions" runat="server"
 OnRowDataBound="gvCommissions_RowDataBound">
 <Columns>
  <asp:TemplateField HeaderText="LOGIN" ItemStyle-Width="29%">
   <ItemTemplate>
    <asp:DropDownList ID="ddlLogin" runat="server" Width="98%" 
     DataTextField="login" DataValueField="id"
     OnSelectedIndexChanged="ddlLogin_SelectedIndexChanged" AutoPostBack="true" >
     </asp:DropDownList>
   </ItemTemplate>
  </asp:TemplateField>
  <asp:TemplateField HeaderText="PHONE" ItemStyle-Width="12%">
   <ItemTemplate>
    <asp:TextBox ID="txtPhone" runat="server" Width="98%" 
    Text='<%# Eval("phone")%>' Enabled="false"></asp:TextBox>
   </ItemTemplate>
  </asp:TemplateField>
 </Columns>
</asp:GridView>

代码隐藏:

protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
         //Get values from DB, store to a datatable and then to a viewstate               
            GetAgentDetails();
         //Adds an empty row to grid                
            SetInitialRow(); 
        }            
    }

private void AddNewRow()
    {
      //Create a datatable 
      dtCurrentData = new DataTable();
      dtCurrentData.Columns.Add("phone");

//Store values of each row to a new datarow. Add all rows to datatable
      foreach (GridViewRow gvRow in gvCommissions.Rows)
        {
          DataRow drcurrentrow = dtCurrentData.NewRow();                      
          drcurrentrow["phone"] = ((TextBox)gvRow.FindControl("txtphone")).Text;
          dtCurrentData.Rows.Add(drcurrentrow);
        }

      //create an empty datarow and also add it to the new datatable.
        DataRow dr = dtCurrentData.NewRow();
        dr["phone"] = "";
        dtCurrentData.Rows.Add(dr);

     //Bind the new datatable to the grid
       gvCommissions.DataSource = dtCurrentData;
       gvCommissions.DataBind();
   }

protected void gvCommissions_RowDataBound(object sender, GridViewRowEventArgs e)
    {
     if (e.Row.RowType == DataControlRowType.DataRow)
      {
        DropDownList ddl = (DropDownList)e.Row.FindControl("ddlLogin");
        dtAgents = (DataTable)ViewState["AgentsTable"];
        ddl.DataSource = dtAgents;
        ddl.DataBind();
        ddl.Items.Insert(0, "");
      }            
    }

【问题讨论】:

  • 如果您还想查看 pageLoad 中的功能,请告诉我。

标签: c# asp.net gridview


【解决方案1】:

当您在 AddNewRow 中进行数据绑定时,原始行会丢失。您必须将下拉选择的索引与您的文本框电话值一起存储在 dtCurrentData 中。然后,您可以使用保存在 dtCurrentData 中的值在 RowDataBound 事件中设置下拉列表的索引。

private void AddNewRow()
{
  //Create a datatable 
  dtCurrentData = new DataTable();
  dtCurrentData.Columns.Add("phone");
  //new column for dropdown index
  dtCurrentData.Columns.Add("ddlIndex");

//Store values of each row to a new datarow. Add all rows to datatable
  foreach (GridViewRow gvRow in gvCommissions.Rows)
    {
      DataRow drcurrentrow = dtCurrentData.NewRow();                      
      drcurrentrow["phone"] = ((TextBox)gvRow.FindControl("txtphone")).Text;
      //get dropdown index
      drcurrentrow["ddlIndex"] = ((DropDownList)gvRow.FindControl("ddlLogin")).SelectedIndex;
      dtCurrentData.Rows.Add(drcurrentrow);
    }

  //create an empty datarow and also add it to the new datatable.
    DataRow dr = dtCurrentData.NewRow();
    dr["phone"] = "";
    //initial drop down index
    dr["ddlIndex"] = 0;
    dtCurrentData.Rows.Add(dr);

    //save to the viewstate like your AgentsTable
    ViewState["CurrentData"] = dtCurrentData;

 //Bind the new datatable to the grid
   gvCommissions.DataSource = dtCurrentData;
   gvCommissions.DataBind();
}

protected void gvCommissions_RowDataBound(object sender, GridViewRowEventArgs e)
{
 if (e.Row.RowType == DataControlRowType.DataRow)
  {
    DropDownList ddl = (DropDownList)e.Row.FindControl("ddlLogin");
    dtAgents = (DataTable)ViewState["AgentsTable"];
    ddl.DataSource = dtAgents;
    ddl.DataBind();
    ddl.Items.Insert(0, "");

    //get the dropdown index from CurrentData
    //use the current gridview's row index, since it matches the datatable
    if (ViewState["CurrentData"] != null)
    {
     DataTable dtCurrentData = (DataTable)ViewState["CurrentData"];
     ddl.SelectedIndex = Convert.ToInt32(dtCurrentData.Rows[e.Row.RowIndex]["ddlIndex"]);
    }

  }            
}

【讨论】:

    【解决方案2】:

    RowDataBound 每次都会被触发(无论页面是 PostBack 页面还是 NOT)。

    您需要在您为RowDataBound 事件中的下拉列表执行数据绑定的代码周围添加if(!IsPostBack) 条件。

    【讨论】:

    • 谢谢。您指的是将默认值绑定到每行的 ddl。那正确吗?如果是这样,则当前代码运行良好。我刚刚添加了一个我想要的示例,以防我的问题令人困惑。
    • 其实我之前很清楚你的问题。如果那不是 PostBack 页面,则应该执行 RowDataBound 事件中的代码行。因为,它当前一直在执行,所以在往返过程中当前总是丢失选择(因为正在分配新数据源,数据绑定并以在列表开头插入 0 结束,这是默认选择)跨度>
    • 有道理。我按照建议添加了,但没有运气。现在所有的 DDL 甚至都没有默认值。在 AddNewRow() 中,我首先存储了文本框值,然后它们再次绑定到相应的字段。这是否也应该采用类似的方式,例如存储登录名/索引等。
    • 你在哪里将数据绑定到网格??
    • 在 AddNewRow() 中。它存储文本框的值,然后再次显示它们。我需要为下拉列表做同样的事情
    猜你喜欢
    • 2014-05-21
    • 2011-03-29
    • 1970-01-01
    • 1970-01-01
    • 2011-08-05
    • 1970-01-01
    • 1970-01-01
    • 2012-09-06
    • 1970-01-01
    相关资源
    最近更新 更多