2
votes

I am working in ASP.Net with C# as code behind. The editor is Visual Studio 2012. I created a GridView with 5 columns: the first one contains checkboxes, the next 3 have text boxes and the last one is a buttonfield, as follows (I have made AutoGenerateColumns as false because, otherwise DataBind adds more columns":

<asp:GridView ID="gvCDS" runat="server" AutoGenerateColumns="False"     OnRowDeleting="gvCDS_RowDeleting">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:CheckBox ID="cbSelectedCDS" runat="server" Enabled="true"/>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText="Module Code">
            <ItemTemplate>
                <asp:TextBox ID="tbxInputCDSModuleCode" runat="server"></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText="Module Name">
            <ItemTemplate>
                <asp:TextBox ID="tbxInputCDSModuleName" runat="server"></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText="Credit Units">
            <ItemTemplate>
                <asp:TextBox ID="tbxInputCDSCreditUnits" runat="server"></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:ButtonField Text="Clear Module" />
    </Columns>

I need to show the GridView on selecting an item from a dropdown. The GridView always needs to have 8 rows. I have written the following code to show the GridView:

DataTable dt = ViewState["dt"] as DataTable;
if (dt == null)
{
    dt = new DataTable();
    dt.Columns.Add("", typeof(Boolean));
    dt.Columns.Add("Module Code", typeof(String));
    dt.Columns.Add("Module Name", typeof(String));
    dt.Columns.Add("Credit Units", typeof(String));

    for (int i = 0; i < 8; i++)
    {
        dt.Rows.Add(dt.NewRow());
    }
}
gvCDS.DataSource = dt;
gvCDS.DataBind();
ViewState["dt"] = dt;
gvCDS.Visible = true;

The user makes some inputs in the GridView and then clicks a button. In the button's click event procedure, I need to delete the checked rows from the GridView and add rows so that total number of rows remains as 8. If I simply call .DeleteRow method, the row is not getting deleted. I still see the GridView as earlier in the browser. So I first copy the content of GridView into DataTable as follows:

DataTable dt = ViewState["dt"] as DataTable;
int rowCounter = 0;
foreach (GridViewRow row in gvCDS.Rows)
{
    DataRow dr = dt.Rows[rowCounter];
    dr[0] = ((CheckBox)row.FindControl("cbSelectedCDS")).Checked;
    dr[1] = ((TextBox)row.FindControl("tbxInputCDSModuleCode")).Text;
    dr[2] = ((TextBox)row.FindControl("tbxInputCDSModuleName")).Text;
    dr[3] = ((TextBox)row.FindControl("tbxInputCDSCreditUnits")).Text;
    rowCounter++;
}

After that, instead of deleting rows from the GridView, I delete from the DataTable as follows:

rowCounter = 0;
int rowsDeleted = 0;
foreach (GridViewRow row in gvCDS.Rows)
{
    if (((CheckBox)row.FindControl("cbSelectedCDS")).Checked)
    {
        dt.Rows.RemoveAt(rowCounter);
        rowsDeleted++;
    }
    else
    {
        rowCounter++;
    }  
}

rowsDeleted now contains the number of rows that were deleted. I add that many rows in the DataTable so that the total number of rows remains as 8.
for (i = 0; i < rowsDeleted; i++)
{
    dt.Rows.Add(dt.NewRow());
}

After that I bind GridView to DataTable as follows:

ViewState["dt"] = dt;
gvCDS.DataSource = dt;
gvCDS.DataBind();

The GridView still has 8 rows. That is correct. But the problem is that the entire GridView has become empty. When testing, I filled some of the rows and checked only one of them. So, the content of the unchecked rows should be there. But the entire GridView is empty. I do not know why. Not only that, I even tested by keeping all rows unchecked, which means no row will be deleted. Still, the GridView becomes all empty. How do I solve this problem? Thank you.

1
I noticed in the code you are using to display the grid that you are explicitly setting the grid to visible: gvCDS.Visible = true;. Is there any reason why you are not doing this on the rebind?Karl Anderson
The grid needs to be shown only if the user selects one particular item from the drop down. So when he selects that item, I set visible to true, else I set visible to false. I have pasted only the portion of the code in which the user selects that particular item. In rebind, the grid is already visible.Avinash

1 Answers

3
votes

Issue is your Text Boxes inside GridView are not bound to any field. Bind their Texts to the fields like Text='<%# Eval("Field")%>'.

Change your GridView markup to this:

<asp:GridView ID="gvCDS" runat="server" AutoGenerateColumns="False"     OnRowDeleting="gvCDS_RowDeleting">
    <Columns>
        <asp:TemplateField>
            <ItemTemplate>
                <asp:CheckBox ID="cbSelectedCDS" runat="server" Enabled="true" />
            </ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText="Module Code">
            <ItemTemplate>
                <asp:TextBox ID="tbxInputCDSModuleCode" Text='<%# Eval("Module Code")%>' runat="server"></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText="Module Name">
            <ItemTemplate>
                <asp:TextBox ID="tbxInputCDSModuleName" Text='<%# Eval("Module Name")%>' runat="server"></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:TemplateField HeaderText="Credit Units">
            <ItemTemplate>
                <asp:TextBox ID="tbxInputCDSCreditUnits"  Text='<%# Eval("Credit Units")%>' runat="server"></asp:TextBox>
            </ItemTemplate>
        </asp:TemplateField>

        <asp:ButtonField Text="Clear Module"/>
    </Columns>
</asp:GridView>