0

First time poster, long time lurker. I am having some trouble with my ASP.NET page, and I hope someone can help me resolve my issue.

Basically, I have a bunch of checkboxes in a gridview, and two buttons: a 'find' button, and a 'save' button. The 'find' can set the value of the checkbox, but if a user unchecks it, I want to capture that change when the user hits 'save'. Currently, it does not work.

Relevant ASPX:

<%@ Page Language="C#" AutoEventWireup="true" EnableViewState="true" CodeBehind="FindTransactions.aspx.cs" Inherits="Basic.FindTransactions" MasterPageFile="~/Trans.Master" %>

Relevant Code Behind here:

Page:

public partial class FindTransactions : System.Web.UI.Page
{
    GridView _gridview = new GridView() { ID = "_gridView" };
    DataTable _datatable = new DataTable();
    Int32 _buyerID = new Int32();

    protected void Page_Load(object sender, EventArgs e)
    {
    }

"Find" button:

protected void Find_Click(object sender, EventArgs e)
{
    //truncated 
    _datatable.Rows.Add(
    //filled with other data from a custom object.
    );

    ViewState["_datatable"] = _datatable;
    ViewState["_buyerID"] = _buyerID;
    BuildGridView((DataTable)ViewState["_datatable"],(Int32)ViewState["buyerID"]);

}

BuildGridView function:

protected void BuildGridView(DataTable d, Int32 b)
{
    _gridview.DataKeyNames = new String[] {"Transaction ID"};
    _gridview.AutoGenerateColumns = false;
    _gridview.RowDataBound += new GridViewRowEventHandler(OnRowDataBound);

    for(Int32 i = 0; i < d.Columns.Count; i++)
    {
        Boundfield boundfield = new BoundField();
        boundfield.DataField = d.Columns[i].ColumnName.ToString();
        boundfield.HeaderText = d.Columns[i].ColumnName.ToString();
        _gridview.Columns.Add(boundfield);
    }

    _gridview.DataSource = d;
    _gridview.DataBind();
    //truncated
    Panel1.Controls.Add(_gridview);
}

Row Bound Event handler:

protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
    if (e.Row.RowType == DataControlRowType.DataRow)
    {
        String controlID = "checkBox";
        CheckBox c = new CheckBox() { ID = controlID};
        c.Enabled = true;

        Boolean success;
        Boolean v;
        success = Boolean.TryParse(e.Row.Cells[8].Text, out v);
        e.Row.Cells[8].Controls.Add(c);

        if (success)
        {
            c.Checked = v;
            if (c.Checked)
            {
                //Will uncomment once other things work
                //e.Row.Visible = false;
            }
        }
        else
        {
            c.Checked = false;
        } 
    }
}

All of that works. Here is where it starts to break down:

"Save" button:

protected void Save_Click(object sender, EventArgs e)
{
    //Both for troubleshooting and both return 0. (Expected for datatable)
    Label1.Text = _gridview.Rows.Count.ToString();
    Label2.Text = _datatable.Rows.Count.ToString();

    /*truncated
    */
    if (grid.Rows.Count == 0)
    {
        BuildGridView((DataTable)ViewState["infoTable"], (Int32)ViewState["guestID"]);
    }
    foreach (GridViewRow r in grid.Rows)
    {
        if (r.RowType == DataControlRowType.DataRow)
        {
             CheckBox cb = (CheckBox)r.FindControl("checkBox");
             if (cb != null && cb.Checked)
             {
                 //This never seems to modify the label.
                 //Will put code to modify database here.
                 Label2.Text += "Hi " + r.RowIndex.ToString();
             }
         }
     }
 }

After I hit the save button, PostBack occurs and GridView is empty (Rows.Count is 0). ViewState appears to be lost before I get a chance to loop through the GridView rows to determine the checkbox values.

At the end of it all, I just want to capture the status of those checkboxes, changed by user interaction or not, by hitting the 'Save' button.

I found some other articles, but a lot of them haven't worked when I tried implementing the various fixes.

This one seems to be the closest that describes my issue, and the code is structured similarly, but I don't quite understand how to implement the fix: GridView doesn't remember state between postbacks

[New simplified code to illustrate problem:]

namespace GridViewIssue
{
    public partial class GridViewNoMaster : System.Web.UI.Page
    {
        GridView _gridView = new GridView() { ID = "_gridView" };
        DataTable _dataTable = new DataTable();

        protected void Page_Load(object sender, EventArgs e)
        {

        }

        protected void Find_Click(object sender, EventArgs e)
        {
            BuildDataTable();

            List<String> list = new List<String>();
            list.Add("1");
            list.Add("User");
            list.Add("10/12/2014");

            foreach (String s in list)
            {
                _dataTable.Rows.Add(
                    list[0],
                    list[1],
                    list[2]
                    );
            }

            BuildGridView();
            //Feedback.Text = _gridView.Rows.Count.ToString();
        }

        protected void Save_Click(object sender, EventArgs e)
        {
            Feedback.Text = "Save Clicked, PostBack: " + IsPostBack + ", GridView Row Count: " + _gridView.Rows.Count + ", GridView ViewState: " + _gridView.EnableViewState;
            foreach (GridViewRow r in _gridView.Rows)
            {
                if(r.RowType == DataControlRowType.DataRow)
                {
                     Feedback.Text = "In DataRow type" + _gridView.Rows.Count;
                }
            }
        }

        protected void BuildDataTable()
        {
            _dataTable.Columns.Add("Transaction ID", typeof(String));
            _dataTable.Columns.Add("Name", typeof(String));
            _dataTable.Columns.Add("Date", typeof(String));
        }

        protected void BuildGridView()
        {
            for (Int32 i = 0; i < _dataTable.Columns.Count; i++)
            {
                BoundField b = new BoundField();
                b.DataField = _dataTable.Columns[i].ColumnName.ToString();
                b.HeaderText = _dataTable.Columns[i].ColumnName.ToString();
                _gridView.Columns.Add(b);
            }

            _gridView.DataKeyNames = new String[] { "Transaction ID" };
            _gridView.AutoGenerateColumns = false;
            _gridView.DataSource = _dataTable;
            _gridView.DataBind();

            Panel1.Controls.Add(_gridView);
        }
    }
}
Community
  • 1
  • 1
  • I made a new project to simplify my page. The the issue persists: – BlurgSchmergal May 29 '15 at 22:08
  • I've also just recently tried using the dispose and unload event handlers of GridView. I didn't think they would work since the object is always there, but I am kind of running out of ideas. – BlurgSchmergal May 30 '15 at 17:52
  • If I could get some help with this, it would be greatly appreciated. I've been trying all sorts of things, but all that I've tried hasn't worked. If more info is needed, or a more thorough explanation is needed, please ask. Thanks! – BlurgSchmergal Jun 02 '15 at 21:13

0 Answers0