C#将空行添加到GridView

时间:2017-10-18 08:54:25

标签: c# asp.net gridview

小问题我已经使用我的代码而无法修复。我有一个带有ImageButton的GridView,它应该添加一个新的空行。出于某种原因,我收到了这个错误:

  

对象引用未设置为对象的实例。描述:   在执行当前期间发生了未处理的异常   网络请求。请查看堆栈跟踪以获取更多信息   错误以及它在代码中的起源。

     

异常详细信息:System.NullReferenceException:对象引用   没有设置为对象的实例。

     

来源错误:

     

执行期间生成了未处理的异常   当前的网络请求。有关的来源和位置的信息   可以使用下面的异常堆栈跟踪来识别异常。

     

堆栈追踪:

     

[NullReferenceException:对象引用未设置为的实例   object。] CTI_DFC.Default.gv_Steps_RowCommand(Object sender,   GridViewCommandEventArgs e)+469
  System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e,Boolean   causeValidation,String validationGroup)+172
  System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Object source,   EventArgs e)+163 System.Web.UI.Control.RaiseBubbleEvent(Object   来源,EventArgs args)+83
  System.Web.UI.Page.ProcessRequestMain(布尔   includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)   3771

所以这是我的GridView:

<asp:GridView ID="gv_Steps" runat="server" CssClass="lbl_user" Font-Names="Verdana" Font-Size="10px" HeaderStyle-Height="23.5px" HorizontalAlign="Center" 
    RowStyle-Height="23.5px" ShowHeaderWhenEmpty="True" style="z-index: 1; left: 8px; top: 143px; position: absolute; height: 20px; width: 1178px;" AutoGenerateColumns="False" OnRowCommand="gv_Steps_RowCommand">
    <AlternatingRowStyle BackColor="#DCE4FF" />
    <Columns>
        <asp:TemplateField HeaderText="Step" HeaderStyle-HorizontalAlign="Left" >
            <ItemTemplate>
                <asp:TextBox ID="txt_Step" HeaderStyle-HorizontalAlign="Left" runat="server" Width="150px" Text='<%# Bind("Step") %>'/>
            </ItemTemplate>
        </asp:TemplateField> 
        <asp:TemplateField HeaderText="Server" HeaderStyle-HorizontalAlign="Left" >
            <ItemTemplate>
                <asp:TextBox ID="txt_Server" HeaderStyle-HorizontalAlign="Left" runat="server" Width="150px" Text='<%# Bind("Server") %>'/>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Type" HeaderStyle-HorizontalAlign="Left" >
            <ItemTemplate>
                <asp:TextBox ID="txt_Type" HeaderStyle-HorizontalAlign="Left" runat="server" Width="150px" Text='<%# Bind("Type") %>'/>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Job" HeaderStyle-HorizontalAlign="Left" >
            <ItemTemplate>
                <asp:TextBox ID="txt_Job" HeaderStyle-HorizontalAlign="Left" runat="server" Width="150px" Text='<%# Bind("Job") %>'/>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="Number" HeaderStyle-HorizontalAlign="Left" >
            <ItemTemplate>
                <asp:TextBox ID="txt_Number" HeaderStyle-HorizontalAlign="Left" runat="server" Width="150px" Text='<%# Bind("Number") %>'/>
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="" ItemStyle-Width="15px" ItemStyle-Wrap="false">
            <ItemTemplate>
                <asp:ImageButton ID="btn_AddRow" runat="server" AlternateText="Add Row" CommandArgument="<%# Container.DataItemIndex %>" CommandName="Add" ImageUrl="./Img/ADD.png" ToolTip="Add Row without Change" />
            </ItemTemplate>
        </asp:TemplateField>
        <asp:TemplateField HeaderText="" ItemStyle-Width="15px" ItemStyle-Wrap="false">
            <ItemTemplate>
                <asp:ImageButton ID="btn_DeleteRow" runat="server" AlternateText="Delete Row" CommandArgument="<%# Container.DataItemIndex %>" CommandName="Delete" ImageUrl="./Img/DEL.png" ToolTip="Delete Row without Change" />
            </ItemTemplate>
        </asp:TemplateField>
    </Columns>
    <HeaderStyle BackColor="#0B4DA2" Font-Bold="True" ForeColor="White" />
    <RowStyle Height="23px" />
</asp:GridView>

这是C#代码,我试图这样做:

protected void gv_Steps_RowCommand(object sender, GridViewCommandEventArgs e)
{
    int intIndex = Convert.ToInt32(e.CommandArgument);  //will be used for Delete

    if (e.CommandName == "Delete" && (gv_Steps.Rows.Count > 1))
    {
        //Nothing done yet
    }
    if (e.CommandName == "Add")
    {
        DataTable dt = gv_Steps.DataSource as DataTable;
        DataRow dr = dt.NewRow();
        dt.Rows.Add(dr);

        gv_Steps.DataSource = dt;
        gv_Steps.DataBind();
    }
}

感谢您的任何建议!

修改

我现在明白我的DataTable是空的并且没有那样工作,但是我如何才能将GridView引入DataSet并返回新的空行?我试着这样做同样的错误:

protected void gv_Steps_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        int intIndex = Convert.ToInt32(e.CommandArgument);  //will be used for Delete

        if (e.CommandName == "Delete" && (gv_Steps.Rows.Count > 1))
        {
            //Nothing done yet
        }
        if (e.CommandName == "Add")
        {
            DataTable dt = GridviewToDataTable();
            DataRow dr = dt.NewRow();
            dt.Rows.Add(dr);

            gv_Steps.DataSource = dt;
            gv_Steps.DataBind();
        }
    }

private DataTable GridviewToDataTable()
    {
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("Step", typeof(string)));
        dt.Columns.Add(new DataColumn("Server", typeof(string)));
        dt.Columns.Add(new DataColumn("Type", typeof(string)));
        dt.Columns.Add(new DataColumn("Job", typeof(string)));
        dt.Columns.Add(new DataColumn("Number", typeof(string)));

        foreach (GridViewRow row in gv_Steps.Rows)
        {
            dt.Rows.Add();
            dt.Rows[row.RowIndex][0] = ((TextBox)row.FindControl("Step")).Text;
            dt.Rows[row.RowIndex][1] = ((TextBox)row.FindControl("Server")).Text;
            dt.Rows[row.RowIndex][2] = ((TextBox)row.FindControl("Type")).Text;
            dt.Rows[row.RowIndex][3] = ((TextBox)row.FindControl("Job")).Text;
            dt.Rows[row.RowIndex][4] = ((TextBox)row.FindControl("Number")).Text;
        }

        return dt;
    }

我得到的错误:

  

对象引用未设置为对象的实例。描述:执行期间发生未处理的异常   当前的网络请求。请查看堆栈跟踪了解更多信息   有关错误的信息以及它在代码中的起源。

     

异常详细信息:System.NullReferenceException:对象引用   没有设置为对象的实例。

     

来源错误:

     

执行期间生成了未处理的异常   当前的网络请求。有关的来源和位置的信息   可以使用下面的异常堆栈跟踪来识别异常。

     

堆栈追踪:

     

[NullReferenceException:对象引用未设置为的实例   对象。] CTI_DFC.Default.GridviewToDataTable()+1161
  CTI_DFC.Default.gv_Steps_RowCommand(对象发送者,   GridViewCommandEventArgs e)+392
  System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e,Boolean   causeValidation,String validationGroup)+172
  System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Object source,   EventArgs e)+163 System.Web.UI.Control.RaiseBubbleEvent(Object   来源,EventArgs args)+83
  System.Web.UI.Page.ProcessRequestMain(布尔   includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)   3771

编辑2

尝试这样:

protected void gv_Steps_RowCommand(object sender, GridViewCommandEventArgs e)
    {
        int intIndex = Convert.ToInt32(e.CommandArgument);  //will be used for Delete

        if (e.CommandName == "Delete" && (gv_Steps.Rows.Count > 1))
        {
            //Nothing done yet
        }
        if (e.CommandName == "Add")
        {
            DataTable dt = GridviewToDataTable(gv_Steps);
            DataRow dr = dt.NewRow();
            dt.Rows.Add(dr);

            gv_Steps.DataSource = dt;
            gv_Steps.DataBind();
            GridviewToDataTable(gv_Steps);
        }
    }
private DataTable GridviewToDataTable(GridView gv)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("Step", typeof(string)));
        dt.Columns.Add(new DataColumn("Server", typeof(string)));
        dt.Columns.Add(new DataColumn("Type", typeof(string)));
        dt.Columns.Add(new DataColumn("Job", typeof(string)));
        dt.Columns.Add(new DataColumn("Number", typeof(string)));
        foreach (GridViewRow row in gv.Rows)
        {
            dt.Rows.Add();
            dt.Rows[row.RowIndex][0] = ((TextBox)row.FindControl("Step")).Text;
            dt.Rows[row.RowIndex][1] = ((TextBox)row.FindControl("Server")).Text;
            dt.Rows[row.RowIndex][2] = ((TextBox)row.FindControl("Type")).Text;
            dt.Rows[row.RowIndex][3] = ((TextBox)row.FindControl("Job")).Text;
            dt.Rows[row.RowIndex][4] = ((TextBox)row.FindControl("Number")).Text;
        }
        gv.DataSource = dt;
        gv.DataBind();
        return dt;
    }

我得到错误:

  

对象引用未设置为对象的实例。描述:   在执行当前期间发生了未处理的异常   网络请求。请查看堆栈跟踪以获取更多信息   错误以及它在代码中的起源。

     

异常详细信息:System.NullReferenceException:对象引用   没有设置为对象的实例。

     

来源错误:

     

执行期间生成了未处理的异常   当前的网络请求。有关的来源和位置的信息   可以使用下面的异常堆栈跟踪来识别异常。

     

堆栈追踪:

     

[NullReferenceException:对象引用未设置为的实例   对象。] CTI_DFC.Default.GridviewToDataTable(GridView gv)+1145
  CTI_DFC.Default.gv_Steps_RowCommand(对象发送者,   GridViewCommandEventArgs e)+407
  System.Web.UI.WebControls.GridView.HandleEvent(EventArgs e,Boolean   causeValidation,String validationGroup)+172
  System.Web.UI.WebControls.GridViewRow.OnBubbleEvent(Object source,   EventArgs e)+163 System.Web.UI.Control.RaiseBubbleEvent(Object   来源,EventArgs args)+83
  System.Web.UI.Page.ProcessRequestMain(布尔   includeStagesBeforeAsyncPoint,Boolean includeStagesAfterAsyncPoint)   3771

还有其他建议吗?

我做到了,就这样完成了:

private DataTable GridviewToDataTable(GridView gv)
    {
        DataTable dt = new DataTable();
        dt.Columns.Add(new DataColumn("Step", typeof(string)));
        dt.Columns.Add(new DataColumn("Server", typeof(string)));
        dt.Columns.Add(new DataColumn("Type", typeof(string)));
        dt.Columns.Add(new DataColumn("Job", typeof(string)));
        dt.Columns.Add(new DataColumn("Number", typeof(string)));
        foreach (GridViewRow row in gv.Rows)
        {
            dt.Rows.Add();
            dt.Rows[row.RowIndex][0] = (row.FindControl("txt_Step") as TextBox).Text;
            dt.Rows[row.RowIndex][1] = (row.FindControl("txt_Server") as TextBox).Text;
            dt.Rows[row.RowIndex][2] = (row.FindControl("txt_Type") as TextBox).Text;
            dt.Rows[row.RowIndex][3] = (row.FindControl("txt_Job") as TextBox).Text;
            dt.Rows[row.RowIndex][4] = (row.FindControl("txt_Number") as TextBox).Text;
        }
        lbl_Fehlermeldung.Text = dt.Rows[0][0].ToString();
        lbl_Fehlermeldung.Visible = true;
        gv.DataSource = dt;
        gv.DataBind();
        return dt;
    }

2 个答案:

答案 0 :(得分:1)

您的数据源为空,这就是您将DataTable转换为null对象并抛出异常的原因

答案 1 :(得分:0)

您的代码仅适用于空gridview。因为你没有增加行索引。

gridview添加新行有一些问题。

您之前在datasource中是否有gridview?如果您之前有datasource,那么您需要将datasource保存在viewstate中,然后在添加新行之前,您需要在gridview中提取以前的数据,然后添加新的一行。

按照以下代码

***首先在datasource

中设置初始行保存viewstate
private void SetInitialRow()
{
    DataTable dt = new DataTable();
    DataRow dr = null;
    dt.Columns.Add(new DataColumn("RowNumber", typeof(string)));
    dt.Columns.Add(new DataColumn("Column1", typeof(string)));
    dt.Columns.Add(new DataColumn("Column2", typeof(string)));
    dt.Columns.Add(new DataColumn("Column3", typeof(string)));
    dr = dt.NewRow();
    dr["RowNumber"] = 1;
    dr["Column1"] = string.Empty;
    dr["Column2"] = string.Empty;
    dr["Column3"] = string.Empty;
    dt.Rows.Add(dr);
    //dr = dt.NewRow();

    //Store the DataTable in ViewState
    ViewState["CurrentTable"] = dt;

    Gridview1.DataSource = dt;
    Gridview1.DataBind();
}

***将其设置为page_load

protected void Page_Load(object sender, EventArgs e)
{
    if (!Page.IsPostBack)
    {
        SetInitialRow(); 
    }
}

***将新行添加到gridview

private void AddNewRowToGrid()
{
    int rowIndex = 0;

    if (ViewState["CurrentTable"] != null)
    {
        DataTable dtCurrentTable = (DataTable)ViewState["CurrentTable"];
        DataRow drCurrentRow = null;
        if (dtCurrentTable.Rows.Count > 0)
        {
            for (int i = 1; i <= dtCurrentTable.Rows.Count; i++)
            {
                //extract the TextBox values
                TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
                TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
                TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");

                drCurrentRow = dtCurrentTable.NewRow();
                drCurrentRow["RowNumber"] = i + 1;

                dtCurrentTable.Rows[i - 1]["Column1"] = box1.Text;
                dtCurrentTable.Rows[i - 1]["Column2"] = box2.Text;
                dtCurrentTable.Rows[i - 1]["Column3"] = box3.Text;

                rowIndex++;
            }
            dtCurrentTable.Rows.Add(drCurrentRow);
            ViewState["CurrentTable"] = dtCurrentTable;

            Gridview1.DataSource = dtCurrentTable;
            Gridview1.DataBind();
        }
    }
    else
    {
        Response.Write("ViewState is null");
    }

    //Set Previous Data on Postbacks
    SetPreviousData();
}

***设置以前的数据

private void SetPreviousData()
{
    int rowIndex = 0;
    if (ViewState["CurrentTable"] != null)
    {
        DataTable dt = (DataTable)ViewState["CurrentTable"];
        if (dt.Rows.Count > 0)
        {
            for (int i = 0; i < dt.Rows.Count; i++)
            {
                TextBox box1 = (TextBox)Gridview1.Rows[rowIndex].Cells[1].FindControl("TextBox1");
                TextBox box2 = (TextBox)Gridview1.Rows[rowIndex].Cells[2].FindControl("TextBox2");
                TextBox box3 = (TextBox)Gridview1.Rows[rowIndex].Cells[3].FindControl("TextBox3");

                box1.Text = dt.Rows[i]["Column1"].ToString();
                box2.Text = dt.Rows[i]["Column2"].ToString();
                box3.Text = dt.Rows[i]["Column3"].ToString();

                rowIndex++;
            }
        }
    }
}

***点击按钮

 protected void ButtonAdd_Click(object sender, EventArgs e)
    {
        AddNewRowToGrid();
    }

Sorce link https://www.aspsnippets.com/Articles/Add-new-Row-to-GridView-on-Button-Click-in-ASPNet.aspx