I have a Gridview "Gridview_ActionPlan" with DataKey "ID" and a RowDataBound event that colors certain cells according to the value of the datasource. Until here everything fine. Now I added a command to give visibility to one column based on a condition and it throws the error "Column 'ID' does not belong to table DefaultView"
if (e.Row.Cells[3].Text != "1" && e.Row.Cells[2].Text != "2")
{
Gridview_ActionPlan.Columns[5].Visible = true;
LinkButton LB2 = e.Row.Cells[5].FindControl("ButtonOpen") as LinkButton;
LB2.Visible = true;
}
... and Columns[5]
<asp:templatefield ItemStyle-HorizontalAlign="center" Visible="false">
<ItemTemplate>
<asp:LinkButton ID="ButtonOpen" runat="server" CommandArgument = '<%# Eval("ID") %>' OnClick="OpenNode" style="vertical-align:text-bottom;text-decoration:none" Visible="false">
<asp:Image runat="server" src="img/plus_.png" id="OpenNodeIMG" border="0" Visible="true"/>
</asp:LinkButton>
</ItemTemplate>
</asp:templatefield>
Now if I give static visibility to that column and remove "Gridview_ActionPlan.Columns[5].Visible = true;" then no error is thrown. This doesn't make sense to me
Martin
Here is the full OnRowDataBound event:
Comment: The SQLConnection part fills the grid with the correct headers according to the chosen language. This is kind of time consuming so if someone has a better idea, feel free... although this is not the issue of that post
protected void OnRowDataBound(object sender, GridViewRowEventArgs e)
{
var gv = (GridView)sender;
string GridID = Convert.ToString(gv.ID);
SqlConnection objConn = new SqlConnection("Data Source=XXXXXX");
SqlDataAdapter adapter = new SqlDataAdapter();
SqlCommand objCommand = new SqlCommand(#"select Text
from EPC_Menu
where language = #language and MenuControlID = #GridID
order by MenuID", objConn);
objCommand.Parameters.Add("#GridID", SqlDbType.NVarChar).Value = GridID;
objCommand.Parameters.Add("#language", SqlDbType.NVarChar).Value = LanguageLabel.Text;
DataSet t = new DataSet();
adapter.SelectCommand = objCommand;
objConn.Open();
adapter.Fill(t);
objConn.Close();
if (e.Row.RowType == DataControlRowType.Header)
{
for(int i = 0; i+6 < gv.Columns.Count; i++)
{
if (t.Tables[0].Rows.Count > 0)
{
e.Row.Cells[i+6].Text = t.Tables[0].Rows[i][0].ToString();
}
}
}
else
{
if (e.Row.Cells[1].Text == "True")
{
e.Row.Cells[9].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
e.Row.Cells[10].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
}
else if (e.Row.Cells[2].Text == "2")
{
e.Row.BackColor = System.Drawing.ColorTranslator.FromHtml("#CCECF4");
}
if (e.Row.Cells[3].Text != "1" && e.Row.Cells[2].Text != "2" && !string.IsNullOrEmpty(e.Row.Cells[3].Text) && e.Row.RowType == DataControlRowType.DataRow && Gridview_ActionPlan.EditIndex != e.Row.RowIndex)
{
LinkButton LB2 = e.Row.Cells[5].FindControl("ButtonOpen") as LinkButton;
LB2.Visible = true;
}
}
}
here goes the gridview with columns 0 - 5 is already posted:
<asp:GridView ID="Gridview_ActionPlan" runat="server"
DataSourceID="ActionPlan"
DataKeyNames="ID"
AutoGenerateColumns="false"
Font-Names="Arial"
OnRowDataBound="OnRowDataBound">
<RowStyle BorderColor="White"
Font-Size="12px" VerticalAlign="Bottom" />
<Columns>
<asp:BoundField DataField="ID"
ItemStyle-CssClass="hiddencol"
HeaderStyle-CssClass="hiddencol" />
<asp:BoundField DataField="CustomerRequired"
ItemStyle-CssClass="hiddencol"
HeaderStyle-CssClass="hiddencol" />
<asp:BoundField DataField="Type"
ItemStyle-CssClass="hiddencol"
HeaderStyle-CssClass="hiddencol" />
<asp:BoundField DataField="CNT"
ItemStyle-CssClass="hiddencol"
HeaderStyle-CssClass="hiddencol" />
<asp:TemplateField ItemStyle-HorizontalAlign="left"
ItemStyle-Width="50px" Visible="false">
<ItemTemplate>
<asp:ImageButton ID="LINKButton2" runat="server"
CommandName="Edit"
ImageUrl="img/edit.png"
Style="vertical-align: text-bottom" />
<asp:LinkButton ID="ButtonSelect" runat="server"
CommandName="Select"
CommandArgument='<%# Eval("ID") %>'
Style="vertical-align: text-bottom; text-decoration: none"
OnClick="AddNewMileStone" Visible="true">
<asp:Image runat="server" ID="ImageMS"
ImageUrl="img/select.png"
Style="vertical-align: text-bottom; text-decoration: none"
BorderStyle="None" />
</asp:LinkButton>
</ItemTemplate>
<EditItemTemplate>
<asp:ImageButton ID="InsertButton" runat="server"
CommandName="Update"
ImageUrl="img/save.png"
Style="vertical-align: text-bottom" />
<asp:ImageButton ID="LINKButton2" runat="server"
CommandName="Cancel"
ImageUrl="img/cancel2.jpg"
Style="vertical-align: text-bottom" />
</EditItemTemplate>
</asp:TemplateField>
<asp:TemplateField ItemStyle-HorizontalAlign="center"
Visible="false">
<ItemTemplate>
<asp:LinkButton ID="ButtonOpen" runat="server"
CommandArgument = '<%# Eval("ID") %>'
OnClick="OpenNode"
style="vertical-align:text-bottom;text-decoration:none"
Visible="false">
<asp:Image id="OpenNodeIMG" runat="server"
src="img/plus_.png"
border="0"
Visible="true"/>
</asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
This is kind of time consuming so if someone has a better idea, feel free... although this is not the issue of that post
Actually this should be a major issue. You are doing three things wrong here.
You are calling the function to fill the dataset in each iteration of RowDataBound. If you have 20 rows and 1 header that will be 20 unnecessary call to database
No need to open() the connection to fill a dataset using a data-adapter
No need to qualify .FindControl with Cells[cell_index]`.
So move your code after your Gridviews DataBind() event. Pseudo code will be,
Gridview_ActionPlan.DataBind();
DataSet t = new DataSet();
var gv = Gridview_ActionPlan;
string GridID = Convert.ToString(gv.ID);
using (SqlConnection objConn = new SqlConnection("Data Source=XXXXXX"))
using (SqlCommand objCommand = new SqlCommand(#"select Text
from EPC_Menu
where language = #language and MenuControlID = #GridID
order by MenuID", objConn))
{
SqlDataAdapter adapter = new SqlDataAdapter();
objCommand.Parameters.Add("#GridID", SqlDbType.NVarChar).Value = GridID;
objCommand.Parameters.Add("#language", SqlDbType.NVarChar).Value = LanguageLabel.Text;
adapter.SelectCommand = objCommand;
adapter.Fill(t);
}
var headerRow = gv.HeaderRow;
for (int i = 0; i + 6 < gv.Columns.Count; i++)
{
if (t.Tables[0].Rows.Count > 0)
{
headerRow.Cells[i + 6].Text = t.Tables[0].Rows[i][0].ToString();
}
}
for (int i = 0; i < gv.Rows.Count; i++)
{
if (gv.Rows[i].Cells[1].Text == "True")
{
gv.Rows[i].Cells[9].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
gv.Rows[i].Cells[10].BackColor = System.Drawing.ColorTranslator.FromHtml("#FFFF00");
}
else if (gv.Rows[i].Cells[2].Text == "2")
{
gv.Rows[i].BackColor = System.Drawing.ColorTranslator.FromHtml("#CCECF4");
}
if (gv.Rows[i].Cells[3].Text != "1" &&
gv.Rows[i].Cells[2].Text != "2" &&
!string.IsNullOrEmpty(gv.Rows[i].Cells[3].Text) &&
gv.Rows[i].RowType == DataControlRowType.DataRow &&
Gridview_ActionPlan.EditIndex != gv.Rows[i].RowIndex)
{
LinkButton LB2 = gv.Rows[i].FindControl("ButtonOpen") as LinkButton;
LB2.Visible = true;
}
}
Related
I have a gridview having a textbox and a checkbox.when the checkbox is checked,a value will be populated into the textbox which a user may alter the value.
Here is the code for the gridview
<asp:GridView ID="gvPayment" runat ="server" AutoGenerateColumns="False" CellPadding="4" ForeColor="#333333" GridLines="Vertical" Width="100%" ShowFooter="true" CssClass="jumbSize1" OnRowDataBound="gvPayment_RowDataBound" AllowPaging="true" PageSize="5" OnPageIndexChanging="gvPayment_PageIndexChanging" >
<Columns>
<asp:TemplateField HeaderStyle-Width="5%">
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" CssClass="checkbox" OnCheckedChanged="chkSelect_CheckedChanged" AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="TRANSACTION DATE" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="SalesDate" runat="server" Text='<%#Eval("Date", "{0:dd/MM/yyyy}") %>' />
</ItemTemplate>
<FooterTemplate>
<asp:Button ID="Submit" Text="Submit" runat="server" OnClick="Submit_Click" CssClass="btn btn-primary" />
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Sales Code" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="SalesCode" runat="server" Text='<%#Eval("SALES_CODE") %>' />
</ItemTemplate>
<FooterTemplate>
<div style="padding: 0 0 5px 0;">
<asp:Label Text="Page Totals" runat="server" align="right" />
</div>
<div>
<asp:Label Text="Grand Totals" runat="server" align="right" />
</div>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ACTUAL SALE" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="ActualSales" runat="server" Text='<%#Eval("ACTUAL", "{0:N2}") %>' />
</ItemTemplate>
<FooterTemplate>
<div style="padding: 0 0 5px 0;">
<asp:Label ID="PageActual" runat="server" align="right" />
</div>
<div>
<asp:Label ID="GrandActual" runat="server" align="right" />
</div>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="ADVANCE" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="AdvPay" runat="server" Text='<%#Eval("ADVANCE", "{0:N2}") %>' />
</ItemTemplate>
<FooterTemplate>
<div style="padding: 0 0 5px 0;">
<asp:Label ID="PageAdvance" runat="server" align="left" />
</div>
<div>
<asp:Label ID="GrandAdvance" runat="server" align="left" />
</div>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="AMOUNT DUE" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:Label ID="AmtDue" runat="server" Text='<%#Eval("DUE", "{0:N2}") %>' />
</ItemTemplate>
<FooterTemplate>
<div style="padding: 0 0 5px 0;">
<asp:Label ID="PageDue" runat="server" align="left" />
</div>
<div>
<asp:Label ID="GrandDue" runat="server" align="left" />
</div>
</FooterTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="AMOUNT PAID" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:TextBox ID="AmtPaid" runat="server" CssClass="form-control CapLock" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<AlternatingRowStyle BackColor="#4870BE" ForeColor="#FFFFFF" />
<FooterStyle BackColor="#76543c" ForeColor="#FFFFFF" Font-Bold="true" />
<HeaderStyle BackColor="#76543c" ForeColor="#FFFFFF" Font-Bold="true" />
<PagerSettings Mode="NextPrevious" NextPageText="Next >>" PreviousPageText="Prev <<" />
<PagerStyle BackColor="#76543c" ForeColor="#FFFFFF" HorizontalAlign="Center" />
<RowStyle BackColor="#EFF3FB" /></asp:Gridview>
Here is the code to bind gridview to data source and get the grand totals in viewstate
private void GetCustomer()
{
dt = new DataTable();
try
{
using (con = new SqlConnection(conString))
{
using (cmd = con.CreateCommand())
{
string query = #"dbo.sp_get_sales";
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = query;
cmd.Parameters.AddWithValue("#ID", CustInfo.SelectedValue);
con.Open();
da = new SqlDataAdapter();
da.SelectCommand = cmd;
da.Fill(dt);
//CALCULATE THE TOTAL AMOUNTS AND HOLD THE VALUE IN A "VIEWSTATE"
ViewState["TotalActual"] = null;
if (ViewState["TotalActual"] == null)
{
Decimal dActual = 0;
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
dActual += dt.Rows[i].Field<Decimal>("ACTUAL");
}
ViewState["TotalActual"] = dActual.ToString("N2");
}
ViewState["TotalAdvance"] = null;
if (ViewState["TotalAdvance"] == null)
{
Decimal dAdvance = 0;
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
dAdvance += dt.Rows[i].Field<Decimal>("ADVANCE");
}
ViewState["TotalAdvance"] = dAdvance.ToString("N2");
}
ViewState["TotalDue"] = null;
if (ViewState["TotalDue"] == null)
{
Decimal dDue = 0;
for (int i = 0; i <= dt.Rows.Count - 1; i++)
{
dDue += dt.Rows[i].Field<Decimal>("DUE");
}
ViewState["TotalDue"] = dDue.ToString("N2");
}
}
//BIND QUERY RESULT WITH THE GRIDVIEW
gvPayment.DataSource = dt;
gvPayment.DataBind();
}
}
catch (Exception ex)
{
ErrorMessage.Text = "An error occured: " + ex.Message;
}
finally
{
con.Close();
con.Dispose();
}
foreach (GridViewRow row in gvPayment.Rows)
{
if (row.RowType == DataControlRowType.DataRow)
{
TextBox AmtPaid = (TextBox)row.FindControl("AmtPaid");
AmtPaid.Attributes.Add("readonly", "readonly");
}
}
}
Here is the code to enable and populate textbox on check changed event
protected void chkSelect_CheckedChanged(object sender, EventArgs e)
{
GridViewRow row = ((GridViewRow)((CheckBox)sender).NamingContainer);
int index = row.RowIndex;
CheckBox chkSelect = (CheckBox)gvPayment.Rows[index].FindControl("chkSelect");
TextBox AmtPaid = (TextBox)gvPayment.Rows[index].FindControl("AmtPaid");
Label AmtDue = (Label)gvPayment.Rows[index].FindControl("AmtDue");
if (chkSelect.Checked && chkSelect != null)
{
AmtPaid.Text = AmtDue.Text.Replace(",", "");
AmtPaid.Attributes.Remove("readonly");
}
else
{
AmtPaid.Text = string.Empty;
AmtPaid.Attributes.Add("readonly", "readonly");
}
}
The textbox get populated with the desired value when the checkbox is selected but both controls lost their values on pageindexchanging event.
I want the checkbox to maintain its state and textbox to maintain whatever value user entered when the pageindexchanging event is called.
Here is the code to move to next page
protected void gvPayment_PageIndexChanging(object sender, GridViewPageEventArgs e)
{
gvPayment.PageIndex = e.NewPageIndex;
GetCustomer();
}
Note: I have gone through all suggested similar questions with no luck or success.
You have to persist them, for example by storing a Disctionary<int, bool> in the ViewState where the key is the RowIndex and the value is the bool(CheckBox is Checked?):
protected void Page_Load(object sender, EventArgs e)
{
if (!IsPostBack)
{
ViewState["EnabledAmtPaidTextBoxes"] = new Dictionary<int, bool>();
GetCustomer();
}
}
I would encapsulate this logic in a method, you need to call it from RowDataBound and CheckedChanged. You don't need that final loop in GetCustomer anymore:
protected void gvPayment_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
EnabledAmtPaidTextBox(e.Row);
}
}
protected void chkSelect_CheckedChanged(object sender, EventArgs e)
{
CheckBox chkSelect = (CheckBox)sender;
GridViewRow row = (GridViewRow)chkSelect.NamingContainer;
EnabledAmtPaidTextBox(row, chkSelect.Checked);
}
private void EnabledAmtPaidTextBox(GridViewRow row, bool? newCheckedOrApplyOld = null)
{
TextBox AmtPaid = (TextBox)row.FindControl("AmtPaid");
Label AmtDue = (Label)row.FindControl("AmtDue");
CheckBox chkSelect = (CheckBox)row.FindControl("chkSelect");
Dictionary<int, bool> enabledAmtPaidTextBoxes = (Dictionary<int, bool>)ViewState["EnabledAmtPaidTextBoxes"];
if (!enabledAmtPaidTextBoxes.ContainsKey(row.RowIndex))
enabledAmtPaidTextBoxes[row.RowIndex] = false;
if (newCheckedOrApplyOld.HasValue)
enabledAmtPaidTextBoxes[row.RowIndex] = newCheckedOrApplyOld.Value;
else
chkSelect.Checked = enabledAmtPaidTextBoxes[row.RowIndex];
if (enabledAmtPaidTextBoxes[row.RowIndex])
{
AmtPaid.Text = AmtDue.Text.Replace(",", "");
AmtPaid.Attributes.Remove("readonly");
}
else
{
AmtPaid.Text = string.Empty;
AmtPaid.Attributes.Add("readonly", "readonly");
}
}
Also, if you use the using-statement you don't need con.Close and con.Dispose in finally because that is done by the using-statement already.
<asp:TemplateField HeaderText="CAT A or CAT C">
<ItemTemplate>
<asp:CheckBox ID="chkcata" OnCheckedChanged="chkcata_CheckedChanged" OnDataBinding="chkcata_DataBinding" runat="server" Text='<%# Eval("cat_a") %>' Checked='<%# Eval("cat_a").ToString().Equals("1")%>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Port to Trikon">
<ItemTemplate>
<asp:CheckBox ID="chkport" Style="text-align: center" OnCheckedChanged="chkport_CheckedChanged" OnDataBinding="chkport_DataBinding" runat="server" Text='<%# Eval("Port_Trikon") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="White Pages Listing? Y/N">
<ItemTemplate>
<asp:CheckBox ID="chkwhilepages" Style="text-align: center" OnCheckedChanged="chkwhilepages_CheckedChanged" OnDataBinding="chkwhilepages_DataBinding" runat="server" Text='<%# Eval("while_pages") %>' />
</ItemTemplate>
</asp:TemplateField>
the image u can see which is my gridview, in which the checkbox are given. Now on update time when i execute my filladd() function the checkbox are not checked even they are true so please help it out..!!
private void filladd(int p)
{
DataTable dt = new DataTable();
dt = b.get_subpaf(p);//MJ SP CHANGE
if (dt.Rows.Count > 0)
{
DataExtensionList.DataSource = dt;
DataExtensionList.DataBind();
ViewState["ExtensionId"] = dt.Rows.Count;
ExtensionBind();
}
}
<asp:CheckBox ID="chkport" runat="server" Checked='<%# DataBinder.Eval (Container.DataItem,"Port_Trikon").ToString()!="0"?true:false %>' />
Make sure that Database is either BIT datatype or just return 1, 0 string
i got the above answer just replace this function with the old one which is asked in question
private void filladd(int p)
{
DataTable dt = new DataTable();
dt = b.get_subpaf(p);//MJ SP CHANGE
if (dt.Rows.Count > 0)
{
DataExtensionList.DataSource = dt;
DataExtensionList.DataBind();
foreach (GridViewRow it1 in DataExtensionList.Rows)
{
CheckBox chk = (CheckBox)it1.FindControl("chkcata");
CheckBox chk1 = (CheckBox)it1.FindControl("chkport");
CheckBox chk2 = (CheckBox)it1.FindControl("chkwhilepages");
if (chk.Text == "True")
{
chk.Checked = true;
}
if (chk1.Text == "True")
{
chk1.Checked = true;
}
if (chk2.Text == "True")
{
chk2.Checked = true;
}
}
}
}
Whenever I delete a row from the gridview which I select to delete, the row above to the selected row gets deleted. Dont know why. Please see my code for deleting.
<asp:GridView ID="grdPostData" runat="server" Width="100%" border="1" Style="border: 1px solid #E5E5E5;" CellPadding="3" AutoGenerateColumns="False" AllowPaging="true" PageSize="10" CssClass="hoverTable" OnPageIndexChanging="grdPostData_PageIndexChanging" OnRowDataBound="grdPostData_RowDataBound" OnRowDeleting="grdPostData_RowDeleting" DataKeyNames="Id">
<AlternatingRowStyle BackColor="#CCCCCC" />
<Columns>
<asp:BoundField DataField="title" HeaderText="Title" ItemStyle-Width="30" ControlStyle-CssClass="k-grid td" />
<asp:BoundField DataField="description" HeaderText="Description" ItemStyle-Width="30" ControlStyle-CssClass="k-grid td" />
<asp:TemplateField HeaderText="Post Category" ItemStyle-Width="50">
<ItemTemplate>
<asp:DropDownList ID="ddlPostCategory" AppendDataBoundItems="true" runat="server"
AutoPostBack="false">
<%-- <asp:ListItem Text="Select" Value="0"></asp:ListItem>--%>
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="active" HeaderText="Active" ItemStyle-Width="30" ControlStyle-CssClass="k-grid td" />
<asp:TemplateField HeaderText="Action" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:ImageButton ID="btnDelete" AlternateText="Delete" ImageUrl="~/images/delete.png" runat="server" Width="15" Height="15" CommandName="Delete" CausesValidation="false" OnClientClick="return confirm('Are you sure you want to delete this record?')" CommandArgument='<%# Eval("Id") %>' />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Image" ItemStyle-Width="15" EditImageUrl="~/images/edit.png" ShowEditButton="True" ControlStyle-Width="15" ControlStyle-Height="15" CancelImageUrl="~/images/close.png" UpdateImageUrl="~/images/update.png">
<ControlStyle Height="20px" Width="20px"></ControlStyle>
</asp:CommandField>
</Columns>
</asp:GridView>
Code behind for your ref:-
protected void grdPostData_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
bool IsDeleted = false;
int Id = Convert.ToInt32(grdPostData.DataKeys[e.RowIndex].Value.ToString());
using (SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultCSRConnection"].ConnectionString))
{
using (SqlCommand cmd = new SqlCommand())
{
cmd.CommandText = "DELETE FROM tbl_Post WHERE Id=#Id";
cmd.Parameters.AddWithValue("#Id", Id);
cmd.Connection = conn;
conn.Open();
IsDeleted = cmd.ExecuteNonQuery() > 0;
conn.Close();
}
}
if (IsDeleted)
{
ScriptManager.RegisterStartupScript(this, this.GetType(), "alert", "alert('Page Succesfully deleted');window.location ='csrposts.aspx';", true);
grdPostData.DataBind();
}
else
{
Response.Write("Some error");
}
}
Please let me know where I am going wrong. I tried debugging the code and the Id was taking 0.
Gridview bindinf Code:-
public void BindGrid()
{
string strQuery = "Select Id, title, description, Active from tbl_Post Order by ID desc";
SqlCommand cmd = new SqlCommand(strQuery);
DataTable dt = GetData(cmd);
grdPostData.DataSource = dt;
grdPostData.DataBind();
}
private DataTable GetData(SqlCommand cmd)
{
DataTable dt = new DataTable();
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultCSRConnection"].ConnectionString);
SqlDataAdapter sda = new SqlDataAdapter();
cmd.CommandType = CommandType.Text;
cmd.Connection = conn;
try
{
conn.Open();
sda.SelectCommand = cmd;
sda.Fill(dt);
return dt;
}
catch (Exception ex)
{
throw ex;
}
finally
{
conn.Close();
sda.Dispose();
conn.Dispose();
}
}
Updated Solution. Completely Working. I am Creating those textboxes in DataBound and theirs a if condition that checks whether Gridview is Empty or Not.
If Gridview is empty then HeaderRow wont be created so that Gridview and Page is able to display else HeaderRow will be Displayed.
Hope this Works for You.
aspx:-
<%# Page Title="" Language="C#" MasterPageFile="~/Master.Master" AutoEventWireup="true"
CodeFile="csrposts.aspx.cs" Inherits="CSRProject.csrposts" %>
<asp:GridView ID="grdPostData" runat="server" Width="100%" border="1" Style="border: 1px solid #E5E5E5;"
CellPadding="3" AutoGenerateColumns="False" AllowPaging="true" PageSize="4" CssClass="hoverTable"
OnPageIndexChanging="grdPostData_PageIndexChanging" OnDataBound="grdPostPageData_DataBound"
OnRowDataBound="grdPostData_RowDataBound" DataKeyNames="Id" OnRowDeleting="grdPostData_RowDeleting"
OnRowEditing="grdPostData_RowEditing" OnRowUpdating="grdPostData_RowUpdating"
OnRowCancelingEdit="grdPostData_RowCancelingEdit">
<AlternatingRowStyle BackColor="#CCCCCC" />
<Columns>
<asp:BoundField DataField="title" HeaderText="Title" ItemStyle-Width="30" ControlStyle-CssClass="k-grid td" />
<asp:BoundField DataField="description" HeaderText="Description" ItemStyle-Width="30"
ControlStyle-CssClass="k-grid td" />
<asp:TemplateField HeaderText="Post Category" ItemStyle-Width="50">
<ItemTemplate>
<asp:DropDownList ID="ddlPostCategory" AppendDataBoundItems="true" runat="server"
AutoPostBack="false">
<%-- <asp:ListItem Text="Select" Value="0"></asp:ListItem>--%>
</asp:DropDownList>
<asp:Label ID="lblId" runat="server" Text='<%# Eval("Id") %>'> </asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="active" HeaderText="Active" ItemStyle-Width="30" ControlStyle-CssClass="k-grid td" />
<asp:TemplateField HeaderText="Action" HeaderStyle-Width="15%">
<ItemTemplate>
<asp:LinkButton ID="lbltbDelete" runat="server" OnClick="lbltbDelete_Click" Text="Delete"
OnClientClick="return confirm('Are you sure you want to delete this record?')"
CausesValidation="false" />
<asp:ImageButton ID="btnDelete" AlternateText="Delete" CommandName="Delete" ImageUrl="~/images/delete.png"
runat="server" Width="15" Height="15" CausesValidation="false" OnClientClick="return confirm('Are you sure you want to delete this record?')" />
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField ButtonType="Image" ItemStyle-Width="15" EditImageUrl="~/images/edit.png"
ShowEditButton="True" ControlStyle-Width="15" ControlStyle-Height="15" CancelImageUrl="~/images/close.png"
UpdateImageUrl="~/images/update.png">
<ControlStyle Height="20px" Width="20px"></ControlStyle>
</asp:CommandField>
</Columns>
<EmptyDataTemplate>
No Result Found
</EmptyDataTemplate>
</asp:GridView>
Aspx.cs
protected void grdPostPageData_DataBound(object sender, EventArgs e)
{
GridViewRow row = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal);
for (int i = 0; i < grdPostData.Columns.Count; i++)
{
TableHeaderCell cell = new TableHeaderCell();
TextBox txtSearch = new TextBox();
txtSearch.Attributes["placeholder"] = grdPostData.Columns[i].HeaderText;
txtSearch.CssClass = "form-control HaydaBre";
cell.Controls.Add(txtSearch);
row.Controls.Add(cell);
}
if (grdPostData.Rows.Count > 0)
{
grdPostData.HeaderRow.Parent.Controls.AddAt(0, row);
}
else
{
}
}
protected void grdPostData_RowDataBound(object sender, GridViewRowEventArgs e)
{
/*
if (e.Row.RowType == DataControlRowType.Header)
{
GridViewRow row = new GridViewRow(0, 0, DataControlRowType.Header, DataControlRowState.Normal);
for (int i = 0; i < grdPostData.Columns.Count; i++)
{
TableHeaderCell cell = new TableHeaderCell();
TextBox txtSearch = new TextBox();
txtSearch.Attributes["placeholder"] = grdPostData.Columns[i].HeaderText;
txtSearch.CssClass = "form-control HaydaBre";
cell.Controls.Add(txtSearch);
row.Controls.Add(cell);
}
grdPostData.HeaderRow.Parent.Controls.AddAt(-1, row);
// e.Row.Parent.Controls.AddAt(1, row);
}
*/
if (e.Row.RowType == DataControlRowType.DataRow)
{
SqlConnection conn = new SqlConnection(System.Configuration.ConfigurationManager.ConnectionStrings["DefaultCSRConnection"].ConnectionString);
SqlCommand cmd = new SqlCommand("select * from tbl_PostCategory ", conn);
cmd.CommandType = CommandType.Text;
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataTable dt = new DataTable();
da.Fill(dt);
if (dt.Rows.Count > 0)
{
DropDownList DropDownList1 =
(DropDownList)e.Row.FindControl("ddlPostCategory");
DropDownList1.DataSource = dt;
DropDownList1.DataTextField = "cat_title";
DropDownList1.DataValueField = "cat_title";
DropDownList1.DataBind();
}
}
}
Row Deleting Code is Same.
Your code looks good. Hope its not a problem from database. Try this
Add this to Gridview
OnRowCommand="GridView_RowCommand"
CodeBehing:-
protected void GridView_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName=="Delete")
{
// Get the value of command argument
int Id= convert.ToInt32(e.CommandArgument);
// Do whatever operation you want.
}
}
Alternatively:-
Add onclick event on your imagebutton of delete and try this
protected void ImageButton_Click(object sender, EventArgs e)
{
ImageButton btn = sender as ImageButton;
GridViewRow gRow = (GridViewRow)btn.NamingContainer;
int id =Convert.ToInt32((gRow.FindControl("lblId") as Label).Text);
}
Update:-
Change your itemtemplate to this
<asp:TemplateField HeaderText="Post Category" ItemStyle-Width="50">
<ItemTemplate>
<asp:DropDownList ID="ddlPostCategory" AppendDataBoundItems="true" runat="server"
AutoPostBack="false">
<%-- <asp:ListItem Text="Select" Value="0"></asp:ListItem>--%>
</asp:DropDownList>
<asp:Label ID="lblId" runat="server" Text='<%# Eval("Id") %>' </asp:Label>
</ItemTemplate>
</asp:TemplateField>
So Fetched Id will be visible next to dropdownlist. Make sure its displaying correct value
I'm working with Outward Challan Detail, in which I need to show the results on a form by a gridview.
My problem is that I don't know how to assign values to textbox existing in the gridview.
How could I assign values in the textbox inside my templates fields that are in my gridview by using dataReader or DataSet?
Here is my aspx
<div id="OutDCItemDetails" runat="server" style="overflow:auto">
<asp:Panel ID="PanelOutDCItemDetails" runat="server">
<asp:GridView ID="gvOutDCItemDetails" runat="server" AllowPaging="True"
PageSize="6" AutoGenerateColumns="False"
onrowdatabound="gvOutDCItemDetails_RowDataBound"
onrowcommand="gvOutDCItemDetails_RowCommand"
onselectedindexchanged="gvOutDCItemDetails_SelectedIndexChanged"
BackColor="White" BorderColor="White" BorderStyle="Ridge" BorderWidth="2px"
CellPadding="3" CellSpacing="1" GridLines="None" DataKeyNames="Item_Id" >
<Columns>
<asp:CommandField ShowDeleteButton="True" />
<asp:BoundField HeaderText="Item Id" DataField="Item_Id" />
<asp:BoundField HeaderText="Item Name" DataField="IName" />
<asp:BoundField HeaderText="Net Quantity" DataField="I_Quantity" />
<asp:BoundField DataField="Remaining_Qty" HeaderText="Remaining Quantity" />
<asp:TemplateField HeaderText="Process">
<ItemTemplate>
<asp:DropDownList ID="ddrProcess" runat="server" >
</asp:DropDownList>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Dispatch Quantity">
<ItemTemplate>
<asp:TextBox ID="txtDispatchQuantity" runat="server" AutoPostBack="true" OnTextChanged="TextChanged_txtDispatchQuantity"></asp:TextBox></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Remaining Quantity">
<ItemTemplate>
<asp:TextBox ID="txtRamainingQuantity" runat="server"></asp:TextBox></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Rate">
<ItemTemplate>
<asp:TextBox ID="txtRate" runat="server" AutoPostBack="true" OnTextChanged="txtRate_TextChanged"></asp:TextBox></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Amount">
<ItemTemplate>
<asp:TextBox ID="txtAmount" runat="server"></asp:TextBox></ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblStatus" runat="server" Text="Status"></asp:Label>
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#C6C3C6" ForeColor="Black" />
<HeaderStyle BackColor="#4A3C8C" Font-Bold="True" ForeColor="#E7E7FF" />
<PagerStyle BackColor="#C6C3C6" ForeColor="Black" HorizontalAlign="Right" />
<RowStyle BackColor="#DEDFDE" ForeColor="Black" />
<SelectedRowStyle BackColor="#9471DE" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#F1F1F1" />
<SortedAscendingHeaderStyle BackColor="#594B9C" />
<SortedDescendingCellStyle BackColor="#CAC9C9" />
<SortedDescendingHeaderStyle BackColor="#33276A" />
</asp:GridView>
Here is my C# code
protected void gvOutDC_SelectedIndexChanged1(object sender, EventArgs e)
{
if (gvOutDC.SelectedIndex >= 0)
{
btnsave.Enabled = false;
btnInword.Visible = false;
OutDC.Visible = true;
OutDCItemDetails.Visible = true;
View.Visible = false;
InwordDetails.Visible = false;
txtOutId.Visible = true;
txtoutCode.Enabled = false;
btn.Visible = true;
txtcustcode.Enabled = false;
btnsave.Enabled = true;
txtOutId.Text = gvOutDC.SelectedDataKey[0].ToString();
txtoutCode.Text = gvOutDC.SelectedRow.Cells[2].Text.ToString();
txtDate.Text =gvOutDC.SelectedRow.Cells[8].Text.ToString();
txtCustomerId.Text = gvOutDC.SelectedRow.Cells[5].Text.ToString();
txtcustcode.Text = gvOutDC.SelectedRow.Cells[7].Text.ToString();
txtCustomerName.Text = gvOutDC.SelectedRow.Cells[6].Text.ToString();
int inworditem = Convert.ToInt16(gvOutDC.SelectedRow.Cells[3].Text.ToString());
SqlCommand cmd = new SqlCommand("sp_getOutDCmaterialDetail",con1);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.AddWithValue("#outDCid", txtOutId.Text);
cmd.Parameters.AddWithValue("#inwordItem", inworditem);
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
//.Text = ds.Tables[0].Rows[0][0].ToString();
con1.Open();
//SqlDataReader dr=cmd.ExecuteReader();
//if (dr.HasRows)
//{
// while (dr.Read())
// {
// }
//}
gvOutDCItemDetails.DataSource = ds;
gvOutDCItemDetails.DataBind();
OutDCItemDetails.Visible = true;
}
}
protected void gvOutDCItemDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//if ((e.Row.RowState & DataControlRowState.Edit) > 0)
//{
DropDownList ddList = (DropDownList)e.Row.FindControl("ddrProcess");
//bind dropdownlist
SqlCommand cmd = new SqlCommand("sp_getProcess", con1);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
DataTable dt = ds.Tables[0];
//DataTable dt = con1.GetData("Select category_name from category");
ddList.DataSource = dt;
ddList.DataTextField = "PName";
ddList.DataValueField = "Process_Id";
ddList.DataBind();
ddList.Items.Insert(0,new ListItem("--SELECT--","0"));
TextBox txtDispatchQuantity = (TextBox)e.Row.FindControl("txtDispatchQuantity");
txtDispatchQuantity.Text = ds.Tables[0].Rows[0][3].ToString();
TextBox txtRamainingQuantity = (TextBox)e.Row.FindControl("txtRamainingQuantity");
txtRamainingQuantity.Text = ds.Tables[0].Rows[0][3].ToString();
TextBox txtRate = (TextBox)e.Row.FindControl("txtRate");
txtRate.Text = ds.Tables[0].Rows[0][3].ToString();
TextBox txtAmount = (TextBox)e.Row.FindControl("txtAmount");
txtAmount.Text = ds.Tables[0].Rows[0][3].ToString();
}
if (e.Row.RowType == DataControlRowType.Footer)
{
// Label lblTotalPrice = (Label)e.Row.FindControl("Total_Amount");
//lblTotalPrice.Text = total.ToString();
// txttotalAmount.Text = Total.ToString();
}
}
You should directly bind the DataTable Column to TextBox inside the TemplateField like...
<asp:TextBox ID="txtDispatchQuantity" runat="server" Text='<%# Eval("ColumnNameInDataSetTable") %>' />
This directly binds the values to TextBoxes. You can do this for all other TextBoxes.
TextBox txtDispatchQuantity = (TextBox)e.Row.FindControl("txtDispatchQuantity");
var dataRow = (DataRowView)e.Row.DataItem;
var Dispatch_Qty = "Dispatch_Qty";
var check = dataRow.Row.Table.Columns.Cast<DataColumn>().Any(x => x.ColumnName.Equals(Dispatch_Qty, StringComparison.InvariantCultureIgnoreCase));
if (check)
{
// Property available
txtDispatchQuantity.Text =ds1.Tables[0].Rows[0][7].ToString();
}
protected void gvOutDCItemDetails_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow)
{
//if ((e.Row.RowState & DataControlRowState.Edit) > 0)
//{
DropDownList ddList = (DropDownList)e.Row.FindControl("ddrProcess");
//bind dropdownlist
SqlCommand cmd = new SqlCommand("sp_getProcess", con1);
cmd.CommandType = CommandType.StoredProcedure;
SqlDataAdapter da = new SqlDataAdapter(cmd);
DataSet ds = new DataSet();
da.Fill(ds);
DataTable dt = ds.Tables[0];
//DataTable dt = con1.GetData("Select category_name from category");
ddList.DataSource = dt;
ddList.DataTextField = "PName";
ddList.DataValueField = "Process_Id";
ddList.DataBind();
ddList.Items.Insert(0,new ListItem("--SELECT--","0"));
TextBox txtDispatchQuantity = (TextBox)e.Row.FindControl("txtDispatchQuantity");
var dataRow = (DataRowView)e.Row.DataItem;
var Dispatch_Qty = "Dispatch_Qty";
var check = dataRow.Row.Table.Columns.Cast<DataColumn>().Any(x => x.ColumnName.Equals(Dispatch_Qty, StringComparison.InvariantCultureIgnoreCase));
if (check)
{
// Property available
txtDispatchQuantity.Text =ds1.Tables[0].Rows[0][7].ToString();
}
}
if (e.Row.RowType == DataControlRowType.Footer)
{
// Label lblTotalPrice = (Label)e.Row.FindControl("Total_Amount");
//lblTotalPrice.Text = total.ToString();
// txttotalAmount.Text = Total.ToString();
}
}
A short way with Simple and Inner Select, For use in ASPX code with no Code Behind:
....
<ItemTemplate>
<tr>
<td>
<asp:Label ID="Label1" runat="server" Text='<%# Eval("COrder") %>' />
</td>
<td>
<asp:Label ID="TitleLabel" runat="server" Text='<%# Eval("CText") %>' />
</td>
<td>
Delete
</td>
</tr>
</ItemTemplate>
....
<asp:SqlDataSource ID="SqlDataSource2" runat="server" ConnectionString="<%$ ConnectionStrings:ConnectionString %>" SelectCommand="SELECT [RId],[CId],[COrder],[CText]=(SELECT [Title] from [Categories] where [ID]=[HomeProduct].[CId]) FROM [HomeProduct] ORDER BY [COrder] DESC"></asp:SqlDataSource>
<asp:Panel ID="pnlFocusAreaPanel" runat="server" GroupingText="Focus Area" Width="800">
<table cellspacing="0" cellpadding="0" width="750">
<tr>
<td>
<asp:GridView ID="dgFocusAreaDetails" runat="server" Width="100%" CssClass="dgStyle"
AutoGenerateColumns="False" BorderColor="Silver" BorderWidth="1px" CellPadding="0"
ShowHeader="False" OnSelectedIndexChanged="dgFocusAreaDetails_SelectedIndexChanged"
DataKeyNames="PK_ID">
<FooterStyle Font-Underline="True" HorizontalAlign="Center" VerticalAlign="Middle">
</FooterStyle>
<Columns>
<asp:TemplateField HeaderText="Focus Area" HeaderStyle-BackColor="Silver">
<ItemStyle Width="90%" />
<ItemTemplate>
<asp:Label runat="server" ID="lblFocusArea" Text='<%# DataBinder.Eval(Container.DataItem, "FOCUS_AREA_NAME").ToString()%>'>
</asp:Label>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Is Current Valid" HeaderStyle-BackColor="Silver">
<ItemStyle Width="10%" HorizontalAlign="Center" />
<ItemTemplate>
<asp:CheckBox ID="chkFocusArea" runat="server" OnCheckedChanged="OnCheckChangedEvent"
AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</td>
</tr>
<tr>
<td align="left">
<asp:TextBox ID="txtFocusArea" runat="server" Width="300px" CausesValidation="true" CssClass="txtStyle" ValidationGroup="focusArea">
</asp:TextBox>
<cc1:TextBoxWatermarkExtender ID="txtFocusAreaWaterMark" runat="server" TargetControlID="txtFocusArea"
WatermarkText="Add Focus Area" WatermarkCssClass="WaterMarkStyle">
</cc1:TextBoxWatermarkExtender>
<asp:Button ID="btnAddFocusArea" runat="server" Text="AddFocusArea" CssClass="btnStyle"
OnClick="btnAddFocusArea_Click" CausesValidation="true" ValidationGroup="focusArea" />
<asp:RequiredFieldValidator ID="reqtxtFocusArea" runat="server" ControlToValidate="txtFocusArea"
ErrorMessage="Please enter focus area" Display="Dynamic" ValidationGroup="focusArea">
</asp:RequiredFieldValidator>
<asp:RegularExpressionValidator ID="regexFocusArea" runat="server" ErrorMessage="Invalid characters(<,>,#)"
ControlToValidate="txtFocusArea" ValidationExpression="^([^<#>]*)$" ValidationGroup="focusArea"
Display="Dynamic" SetFocusOnError="true">
</asp:RegularExpressionValidator>
</td>
</tr>
</table>
</asp:Panel>
and in code behind
protected void btnAddFocusArea_Click(object sender, EventArgs e)
{
string strFocusArea = txtFocusArea.Text;
OleDbConnection myConnection = new OleDbConnection(ConfigurationSettings.AppSettings["SQLConnectionString"]);
if (strFocusArea == string.Empty || strFocusArea == txtFocusAreaWaterMark.WatermarkText)
{
lblError.Text = "Focus area is not entered";
}
else
{
string insertQuery = "INSERT INTO LK_CODECAT_FOCUS_AREA(FOCUS_AREA_NAME,FK_ADDED_BY,ADDED_ON) "+
" VALUES('" + strFocusArea + "', "+Session["UserID"] +", GETDATE())";
try
{
myConnection.Open();
OleDbCommand myCommandToInsert = new OleDbCommand(insertQuery, myConnection);
myCommandToInsert.ExecuteNonQuery();
}
catch(Exception exc)
{
ExceptionLogger.LogException(exc);
}
finally
{
if (myConnection != null)
{
myConnection.Close();
}
}
PopulateFocusArea();
}
txtFocusArea.Text = txtFocusAreaWaterMark.WatermarkText;
}
private void PopulateFocusArea()
{
OleDbConnection myConnection = new OleDbConnection(ConfigurationSettings.AppSettings["SQLConnectionString"]);
string selectQuery = "SELECT PK_ID, FOCUS_AREA_NAME, IS_CURRENT_FOCUS FROM LK_CODECAT_FOCUS_AREA LKCFA ORDER BY FOCUS_AREA_NAME";
if (Session["RoleID"].ToString() == "1" || ((Session["WorkID"].ToString() != "9") ||
(Session["WorkID2"].ToString() != "9") ||
(Session["WorkID3"].ToString() != "9")))
{
try
{
myConnection.Open();
OleDbCommand myCommandFocusArea = new OleDbCommand(selectQuery, myConnection);
OleDbDataAdapter myAdapter = new OleDbDataAdapter(myCommandFocusArea);
DataSet ds = new DataSet();
myAdapter.Fill(ds);
dgFocusAreaDetails.DataSource = ds;
dgFocusAreaDetails.ShowHeader = true;
dgFocusAreaDetails.DataBind();
}
catch (Exception exc)
{
ExceptionLogger.LogException(exc);
}
finally
{
if (myConnection != null)
{
myConnection.Close();
}
}
}
}
protected void dgFocusAreaDetails_SelectedIndexChanged(object sender, EventArgs e)
{
string selectedCategory = dgFocusAreaDetails.SelectedRow.Cells[1].Text;
int index = dgFocusAreaDetails.SelectedIndex;
lblError.Text = dgFocusAreaDetails.DataKeys[index].Value.ToString();
}
public void OnCheckChangedEvent(object sender, EventArgs e)
{
CheckBox chk = (CheckBox)sender;
string chkfocusarea = ((Control)chk).ID;
//string focusAreaDetails = dgFocusAreaDetails.SelectedRow.Cells[0].Text;
int index =Convert.ToInt32(dgFocusAreaDetails.SelectedIndex);
if (chk.Checked)
{
string updateQuery = "UPDATE [LK_CODECAT_FOCUS_AREA] SET [IS_CURRENT_FOCUS] = 1 WHERE PK_ID = "
+Convert.ToInt32( dgFocusAreaDetails.DataKeys[index].Value)+" ";
}
else
{
lblError.Text = "unchecked";
}
}
i want to know how i find the datakeyvalue on checked event because updateQuery in checked event is generating exception.
Could you add a asp:button instead of using the checkbox on your GridView and fire an OnRowUpdating event?
Alternatively you could store the index value in a session varaible to pick up on your chkbox click.
edit: found this post is that any help?
They suggest you have to check each row to see if the value has changed.