I have a gridview which is created on a button click. It has some checkboxes so the user can adjust the CRUD access rights for certain pages and then save all rows.
I have another button to save the rows where I loop through, getting the rowID and the access rights to save.
I am having a problem when saving, it can't find the control in the row and when it gets to ID= I get a object referenced exception. If I do the checkbox assignments first, I get the error on the C= part.
protected void btnSave_Click(object sender, EventArgs e)
{
foreach (GridViewRow r in gvRights.Rows)
{
if (r.RowType == DataControlRowType.DataRow)
{
int ID;
ID = Convert.ToUInt16(r.Cells[0].ToString());
bool C, R, U, D;
CheckBox chkC = r.FindControl("chkC") as CheckBox;
C = chkC.Checked;
CheckBox chkR = r.FindControl("chkR") as CheckBox;
R = chkR.Checked;
CheckBox chkU = r.FindControl("chkU") as CheckBox;
U = chkU.Checked;
CheckBox chkD = r.FindControl("chkD") as CheckBox;
D = chkD.Checked;
}
}
}
Gridview:
<asp:GridView ID="gvRights" runat="server" Width="100%" BackColor="White" BorderColor="#999999" BorderStyle="None" BorderWidth="1px" CellPadding="3" GridLines="Vertical" AutoGenerateColumns="False" OnRowDataBound="gvRights_RowDataBound">
<AlternatingRowStyle BackColor="#DCDCDC" />
<Columns>
<asp:BoundField DataField="ID" HeaderText="Page ID" />
<asp:BoundField DataField="PageName" HeaderText="Page Name" />
<asp:BoundField DataField="PageDesc" HeaderText="Page Desc" />
<asp:TemplateField HeaderText="Create"></asp:TemplateField>
<asp:TemplateField HeaderText="Read"></asp:TemplateField>
<asp:TemplateField HeaderText="Update"></asp:TemplateField>
<asp:TemplateField HeaderText="Delete"></asp:TemplateField>
</Columns>
<FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
<HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<RowStyle BackColor="#EEEEEE" ForeColor="Black" />
<SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#F1F1F1" />
<SortedAscendingHeaderStyle BackColor="#0000A9" />
<SortedDescendingCellStyle BackColor="#CAC9C9" />
<SortedDescendingHeaderStyle BackColor="#000065" />
</asp:GridView>
If you are adding your checkboxes programmatically you need to add them back in on each page load in the pageinit (before page_load). This way the controls are added on each postback and will get their values filled from the viewstate.
An easier way is to actually add the Checkboxes in your template field in the definition
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox runat="server" ID="chkC" />
</ItemTemplate>
<EditItemTemplate>
<asp:CheckBox runat="server" ID="chkC" />
</EditItemTemplate>
</asp:TemplateField>
Related
I have a problem that is most likely easy but I'm missing something small.
I have looked at numerous entries on Stack Overflow with the same question but I must be doing something wrong.
I am trying to get the value of a textbox in a GridView after typing into it. I want to take that value and update a SQL field.
Here is my GridView:
<asp:GridView ID="ASPxGridView1" runat="server" AutoGenerateColumns="False" DataKeyNames="SALESID" HeaderStyle-HorizontalAlign="CENTER" HorizontalAlign="CENTER" CellPadding="4" ForeColor="#333333" GridLines="Both" AllowSorting="true" AllowPaging="true" PageSize="100" OnRowDataBound="ASPxGridView1_RowDataBound" OnSorting="ASPxGridView1_Sorting" OnRowUpdating="ASPxGridView1_RowUpdating">
<AlternatingRowStyle BackColor="White" ForeColor="#284775" />
<Columns>
<%-- 0 This is e.Row.Cells[0].Text --%>
<asp:BoundField DataField="SALESID" HeaderText="SALES ORDER" SortExpression="SALESID" HeaderStyle-CssClass="padLeft" HeaderStyle-Width="125" ItemStyle-Width="115">
<HeaderStyle HorizontalAlign="Center" />
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<%-- 1 --%>
<asp:BoundField DataField="ITEMID" HeaderText="PART NUMBER" HeaderStyle-HorizontalAlign="Center" SortExpression="ITEMID" ItemStyle-Width="150" >
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<%-- 2 --%>
<asp:BoundField DataField="NAME" HeaderText="PART NAME" HeaderStyle-HorizontalAlign="Center" SortExpression="NAME" ItemStyle-Width="320">
<HeaderStyle HorizontalAlign="Center" />
<ItemStyle HorizontalAlign="Left" />
</asp:BoundField>
<%-- 3 --%>
<asp:BoundField DataField="CUSTACCOUNT" HeaderText="ACC" HeaderStyle-HorizontalAlign="Center" SortExpression="CUSTACCOUNT">
<ItemStyle HorizontalAlign="Left" />
</asp:BoundField>
<%-- 4 --%>
<asp:BoundField DataField="SALESNAME" HeaderText="CUSTOMER" HeaderStyle-HorizontalAlign="Center" SortExpression="SALESNAME" ItemStyle-Width="350" >
<ItemStyle HorizontalAlign="Left" />
</asp:BoundField>
<%-- 5 --%>
<asp:BoundField DataField="SHIPPINGDATECONFIRMED" HeaderText="SHIPPING DATE" HeaderStyle-HorizontalAlign="Center" SortExpression="SHIPPINGDATECONFIRMED" ItemStyle-Width="100" >
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<%-- 6 --%>
<asp:BoundField DataField="QTYORDERED" HeaderText="QTY ORDERED" HeaderStyle-HorizontalAlign="Center" SortExpression="QTYORDERED" >
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<%-- 7 --%>
<asp:BoundField DataField="REMAINSALESPHYSICAL" HeaderText="QUANTITY REMAINED" HeaderStyle-HorizontalAlign="Center" SortExpression="REMAINSALESPHYSICAL" >
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<%-- 8 --%>
<asp:BoundField DataField="AVAILPHYSICAL" HeaderText="AVAIL PHYSICAL" HeaderStyle-HorizontalAlign="Center" SortExpression="AVAILPHYSICAL" ItemStyle-Width="80" >
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<%-- 9 --%>
<asp:HyperLinkField DataTextField="WMSLOCATIONID" HeaderText="LOCATION" HeaderStyle-HorizontalAlign="Center" DataNavigateURLFields="ITEMID" DataNavigateURLFormatString="~\Location.aspx?ITEMID={0}" Target="_blank" SortExpression="WMSLOCATIONID">
<ItemStyle HorizontalAlign="Center" />
</asp:HyperLinkField>
<%-- 10 --%>
<asp:HyperLinkField DataTextField="INPROCESS" HeaderText="IN PROCESS" HeaderStyle-HorizontalAlign="Center" DataNavigateUrlFields="ITEMID" DataNavigateUrlFormatString="~\InProcess.aspx?ITEMID={0}" Target="_blank" SortExpression="INPROCESS">
<ItemStyle HorizontalAlign="Left" />
</asp:HyperLinkField>
<%-- 11 --%>
<asp:BoundField DataField="PRD" HeaderText="PRD" HeaderStyle-HorizontalAlign="Center" SortExpression="PRD" ItemStyle-Width="135">
<ItemStyle HorizontalAlign="Center" />
</asp:BoundField>
<%-- 12 --%>
<asp:TemplateField HeaderText="SHIPTODAY" ItemStyle-Width="90">
<ItemTemplate>
<asp:TextBox ID="SHIPTODAY" runat="server"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<%-- 13 --%>
<asp:TemplateField HeaderText="NOTES" >
<ItemTemplate>
<asp:TextBox ID="NOTES" runat="server" TextMode="MultiLine"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField ButtonType="Button" HeaderText="" CommandName="Update" Text="Update" />
</Columns>
<EditRowStyle BackColor="#999999" />
<FooterStyle BackColor="#5D7B9D" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#284775" Font-Bold="True" ForeColor="White" HorizontalAlign="Center" />
<PagerStyle BackColor="#284775" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#F7F6F3" ForeColor="#333333" />
<SelectedRowStyle BackColor="#E2DED6" Font-Bold="False" ForeColor="#333333" />
<SortedAscendingCellStyle BackColor="#E9E7E2" />
<SortedAscendingHeaderStyle BackColor="#506C8C" />
<SortedDescendingCellStyle BackColor="#FFFDF8" />
<SortedDescendingHeaderStyle BackColor="#6F8DAE" />
</asp:GridView>
Here is my gridview _RowUpdating method:
protected void ASPxGridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
Debug.WriteLine("row updating");
int index = Convert.ToInt32(e.RowIndex);
Debug.WriteLine("Index: " + index);
GridViewRow selectedRow = ASPxGridView1.Rows[index];
TableCell itemIDSelected = selectedRow.Cells[1];
TableCell rowPRD = selectedRow.Cells[11];
TableCell rowShipToday = selectedRow.Cells[12];
TableCell rowNotes = selectedRow.Cells[13];
string itemIdSelectedText = itemIDSelected.Text;
string rowPRDSelected = rowPRD.Text;
string rowShipTodaySelected = rowShipToday.Text;
string test = ((TextBox)selectedRow.FindControl("NOTES")).Text;
string test1 = ((TextBox)ASPxGridView1.Rows[index].FindControl("NOTES")).Text;
TextBox test2 = ASPxGridView1.Rows[index].FindControl("NOTES") as TextBox;
string test2text = test2.Text;
//string rowNotesSelected = rowNotes.Text;
//Debug.WriteLine(itemIdSelectedText);
//Debug.WriteLine(itemIdSelectedText);
//Debug.WriteLine(rowPRDSelected);
//Debug.WriteLine(rowShipTodaySelected);
Debug.WriteLine(test1);
Debug.WriteLine(test);
Debug.WriteLine(test2text);
//Debug.WriteLine(selectedRow.Cells[0].Text);
//Debug.WriteLine(selectedRow.Cells[1].Text);
//Debug.WriteLine(selectedRow.Cells[2].Text);
//Debug.WriteLine(selectedRow.Cells[3].Text);
//Debug.WriteLine(selectedRow.Cells[4].Text);
//Debug.WriteLine(selectedRow.Cells[5].Text);
//Debug.WriteLine(selectedRow.Cells[6].Text);
//Debug.WriteLine(selectedRow.Cells[7].Text);
//Debug.WriteLine(selectedRow.Cells[8].Text);
//Debug.WriteLine(selectedRow.Cells[9].Text);
//Debug.WriteLine(selectedRow.Cells[10].Text);
Debug.WriteLine(selectedRow.Cells[11].Text);
//Debug.WriteLine(selectedRow.Cells[12].Text);
//Debug.WriteLine(selectedRow.Cells[13].Text);
Debug.WriteLine("-----------");
//Debug.WriteLine(rowShipTodaySelected);
//Debug.WriteLine(rowNotesSelected);
}
When I run this and I type something in, the debug writeline's show.
I know i'm on the correct line because the index is correct per the line I am clicking the Update button on.
Sample debug output from above looks like this:
row updating
Index: 5
D31948P01
PRD-00030521
PRD-00030521
I cannot seem to get the value of the NOTES TextBox field.
As you can see with my testing I've tried using a FindControl and I've tried having it as a TextBox and also trying to get it directly to a string.
I've set breakpoints and each time I do it the test variable is null.
I'm missing something and I do not know what.
To summarize:
On non-text fields I can pull the data from the field.
On TextBox fields I cannot even using the FindControl method.
What I want to do:
Get the TextBox field value in the GridView so I can update the database.
StackOverflow links I've tried before asking this question:
c# Get value (text) of a bound textbox in a gridview
How to get value of TextBox of GridView in C#?
Manipulate textbox on gridview C#
Get TextBox value from GridView cell
ASP.net C# Gridview ButtonField onclick event
Thanks in advance. I've spent over 6 hours of attempting this without results. I don't understand it well enough yet. If there are any tutorials or videos explaining GridView's please let me know what they are so I can understand better.
The reason why RowUpdating method cannot find the text inside the textbox is most likely because of the postback. Clicking update button causes a post back to server. Before ASPxGridView1_RowUpdating is called, there is an a call to re-build the gridview ie.: ASPxGridView1.DataBind(). To avoid this, wrap the databind in an if (!Page.IsPostBack)
Below is a basic working example
<asp:GridView ID="ASPxGridView1"
runat="server"
AutoGenerateColumns="False"
OnRowUpdating="ASPxGridView1_RowUpdating">
<Columns>
<asp:TemplateField HeaderText="NOTES" >
<ItemTemplate>
<asp:TextBox ID="NOTES" runat="server" TextMode="MultiLine"></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:ButtonField ButtonType="Button" HeaderText="" CommandName="Update" Text="Update" />
</Columns>
</asp:GridView>
Code behind:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// This code will not be reached if you click update button.
var data = new string[] { "a", "b", "c" };
ASPxGridView1.DataSource = data;
ASPxGridView1.DataBind();
}
}
protected void ASPxGridView1_RowUpdating(object sender, GridViewUpdateEventArgs e)
{
int index = Convert.ToInt32(e.RowIndex);
GridViewRow selectedRow = ASPxGridView1.Rows[index];
TextBox txtNotes = (TextBox)selectedRow.FindControl("NOTES");
Debug.WriteLine(txtNotes.Text);
}
I have a nested grid with checkbox in both grid. The checkbox in parent grid has a OnCheckedChanged event to check all checkbox in the parent grid, and another to check all checkbox in the child grid with checkbox in each row.
ASPX
<asp:GridView ID="gvSelect" runat="server" AutoGenerateColumns="false" OnRowDataBound="gvSelect_DataBound"
BackColor="White" BorderColor="#CC9966" BorderStyle="None" BorderWidth="1px" CellPadding="4" DataKeyNames="ItemNumber">
<Columns>
<asp:BoundField Visible="False" DataField="RecordUID" SortExpression="RecordUID" HeaderText="RecordUID" ReadOnly="True" />
<asp:TemplateField>
<ItemTemplate>
<img alt = "" style="cursor: pointer" src="Images/plus.png" id="ExpandRows" class="expand" />
<asp:Panel ID="pnlSelectExpand" runat="server" Style="display: none">
<asp:GridView ID="gvSelectExpand" runat="server" Width="350px" AutoGenerateColumns="false" DataKeyNames="Slab">
<Columns>
<asp:TemplateField HeaderText="Select">
<ItemTemplate>
<asp:CheckBox ID="chkSelectExpand" runat="server" OnCheckedChanged="chkSelectExpand_CheckedChanged" AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Slab" SortExpression="Slab" ReadOnly="True" HeaderText="Slab" />
<asp:BoundField DataField="Size" SortExpression="Size" ReadOnly="True" HeaderText="Size" />
<asp:BoundField DataField="Sqft" SortExpression="Sqft" ReadOnly="True" HeaderText="Sqft" ItemStyle-HorizontalAlign="Right" />
<asp:BoundField DataField="Block" SortExpression="Block" ReadOnly="True" HeaderText="Block" ItemStyle-HorizontalAlign="Right" />
<asp:BoundField DataField="Totalweight" SortExpression="Totalweight" ReadOnly="True" HeaderText="Totalweight" ItemStyle-HorizontalAlign="Right" />
</Columns>
<RowStyle ForeColor="#663399" />
<FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" HorizontalAlign="Right" />
<PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<HeaderStyle Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000" />
</asp:GridView>
</asp:Panel>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Select">
<HeaderTemplate>
<asp:CheckBox ID="chkSelectAll" runat="server" Font-Names="Verdana" Font-Size="XX-Small" Text="Select All Slabs"
OnCheckedChanged="chkSelectAll_CheckedChanged" AutoPostBack="true" />
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" OnCheckedChanged="chkSelect_CheckedChanged" AutoPostBack="true" />
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="Bundle" SortExpression="Bundle" ReadOnly="True"
HeaderText="Bundle" />
<asp:BoundField DataField="ItemNumber" SortExpression="ItemNumber"
ReadOnly="True" HeaderText="ItemNumber" />
<asp:BoundField DataField="ItemDescription" SortExpression="ItemDescription"
ReadOnly="True" HeaderText="ItemDesc" />
<asp:BoundField DataField="whse" SortExpression="whse" ReadOnly="True"
HeaderText="Warehouse" />
<asp:BoundField DataField="NumSlabs" SortExpression="NumSlabs" ReadOnly="True"
HeaderText="NumSlabs" ItemStyle-HorizontalAlign="Right" />
<asp:BoundField DataField="QtyTiedUp" SortExpression="QtyTiedUp" ReadOnly="True"
HeaderText="QtyTiedUp" ItemStyle-HorizontalAlign="Right" />
</Columns>
<PagerSettings Position="TopAndBottom" />
<RowStyle ForeColor="#663399" />
<FooterStyle BackColor="#990000" Font-Bold="True" ForeColor="White" HorizontalAlign="Right" />
<PagerStyle BackColor="#FFCC66" ForeColor="#333333" HorizontalAlign="Center" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="Navy" />
<HeaderStyle Font-Bold="True" ForeColor="#FFFFCC" BackColor="#990000" />
</asp:GridView>
Here are my code behind for the OnCheckedChanged
CS
protected void chkSelectAll_CheckedChanged(object sender, EventArgs e)
{
CheckBox ChkBoxHeader = (CheckBox)gvSelect.HeaderRow.FindControl("chkSelectAll");
foreach (GridViewRow row in gvSelect.Rows)
{
CheckBox ChkBoxRows = (CheckBox)row.FindControl("chkSelect");
if (ChkBoxHeader.Checked == true)
{
ChkBoxRows.Checked = true;
}
else
{
ChkBoxRows.Checked = false;
}
bool status = ChkBoxRows.Checked;
GridView gvSelectExpand = (GridView)row.FindControl("gvSelectExpand");
foreach (GridViewRow gvSelectExpandRow in gvSelectExpand.Rows)
{
CheckBox chkSelectExpand = (CheckBox)gvSelectExpandRow.FindControl("chkSelectExpand");
if (status)
chkSelectExpand.Checked = true;
else
chkSelectExpand.Checked = false;
}
}
}
protected void chkSelect_CheckedChanged(object sender, EventArgs e)
{
CheckBox ckb = (CheckBox)sender;
GridViewRow row = (GridViewRow)ckb.NamingContainer;
CheckBox ChkBoxRows = (CheckBox)row.FindControl("chkSelect");
bool status = ChkBoxRows.Checked;
GridView gvSelectExpand = (GridView)row.FindControl("gvSelectExpand");
foreach (GridViewRow gvSelectExpandRow in gvSelectExpand.Rows)
{
CheckBox chkSelectExpand = (CheckBox)gvSelectExpandRow.FindControl("chkSelectExpand");
if (status)
chkSelectExpand.Checked = true;
else
chkSelectExpand.Checked = false;
}
}
protected void chkSelectExpand_CheckedChanged(object sender, EventArgs e)
{
;
}
Question
The issue is
when I have the chkSelect(checkbox in parent grid row) checked, if I tried to uncheck 1 or more of the chkSelectExpand(checkbox in child grid), it will do a postback and end up checked all checkbox in that child grid again.
If the chkSelect is not checked, I do not have this issue.
However the postback doesn't triggers chkSelect_CheckedChanged, I put a breakpoint by the function in debug so I can be sure about it.
How do I fix this issue? Please help me out, thanks.
I found somewhat an answer to my own question, and it has to do with how the child grid is displayed.
The following code hide the true child grid in the cell of the parent grid. The reason I call it the true child grid is cause if I perform the same action on this grid, everything works as expected, right, and functional.
<asp:Panel ID="pnlSelectExpand" runat="server" Style="display: none">
I believe it has to do with how the expandable panel works, which is the following code
<img alt = "" style="cursor: pointer" src="Images/plus.png" id="ExpandRows" class="expand" />
Marking the true child grid cg1, expandable grid cg2. When the checkbox of the parent grid is checked, updating the checkbox in cg1 will also update cg2, but not the other way around. Meaning cg2 is a mirror, or a one way pointer to cg1 that just won't update the true child grid.
If anyone has other suggestion or answer please correct me. I am posting my finding here just for anyone stumble upon the same issue and hopefully he/she will not waste much time as I did.
I have a grid with several data columns and a column with check boxes. There is a column called app Number which contains numbers. Now I want to select number in the checked rows and put them into an array. How can I do it?
Here is the code I have done up to now.
<asp:GridView ID="gvAppeals" runat="server" BackColor="White" BorderColor="#CC9966" BorderStyle="None" BorderWidth="1px" CellPadding="4"
Width="665px" AutoGenerateColumns="False" OnSelectedIndexChanged="gvAppeals_SelectedIndexChanged1"
AllowPaging="True" PageSize="10" OnPageIndexChanging="gvAppeals_PageIndexChanging" OnRowDataBound="gvAppeals_RowDataBound">
<Columns>
<asp:BoundField DataField="App_no" HeaderText="APP NO">
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle Font-Size="Small" HorizontalAlign="Left" VerticalAlign="Middle" />
</asp:BoundField>
<asp:BoundField DataField="EMP_FULLNAME" HeaderText="FULL NAME">
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle Font-Size="Small" HorizontalAlign="Left" VerticalAlign="Middle" />
</asp:BoundField>
<asp:BoundField DataField="EMP_NIC_NO" HeaderText="NIC">
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle Font-Size="Small" HorizontalAlign="Left" VerticalAlign="Middle" />
</asp:BoundField>
<asp:BoundField DataField="EMP_BIRTHDAY" HeaderText="BIRTH DATE" DataFormatString="{0:yyyy-MM-dd}">
<HeaderStyle HorizontalAlign="Left" />
<ItemStyle Font-Size="Small" HorizontalAlign="Left" VerticalAlign="Middle" />
</asp:BoundField>
<asp:TemplateField>
<%--<HeaderTemplate>
<asp:CheckBox ID="chkHeader" runat="server" AutoPostBack="true" />
</HeaderTemplate>--%>
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#FFFFCC" ForeColor="#330099" />
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="White" HorizontalAlign="Left" />
<PagerStyle BackColor="#FFFFCC" ForeColor="#330099" HorizontalAlign="Center" />
<RowStyle BackColor="White" ForeColor="Black" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="#663399" />
<SortedAscendingCellStyle BackColor="#FEFCEB" />
<SortedAscendingHeaderStyle BackColor="#AF0101" />
<SortedDescendingCellStyle BackColor="#F6F0C0" />
<SortedDescendingHeaderStyle BackColor="#7E0000" />
</asp:GridView>
C# code
protected void btnConfirm_Click(object sender, EventArgs e)
{
//DataSet ds = new DataSet();
int[] numbers;
numbers = new int[gvAppeals.Rows.Count];
int noOfRowsChecked = 0;
foreach (GridViewRow row in gvAppeals.Rows)
{
int rowIndex = row.RowIndex;
CheckBox chkrow = (CheckBox)row.FindControl("chkSelect");
if (chkrow.Checked == true)
{
numbers[noOfRowsChecked] = Int32.Parse(gvAppeals.DataKeys[rowIndex]["App_no"].ToString());
noOfRowsChecked++;
}
//update the dept by checking the selected appeal numbers
if (noOfRowsChecked > 0)
{
for (int i = 0; i < numbers.Length; i++)
{
int appNo = numbers[i];
dba.confirmAppeal(appNo);
}
}
else
{
WebMsgBox.Show("Please select an application to confirm");
}
}
}
Just a gentle reminder that you need to subtract one (-1) on your indexing. That's probably the reason you're getting System.ArgumentOutOfRangeException.
There are no DataKeys defined in the GridView, to it will always be out of range. Add the DataKeyNames property to the GridView.
<asp:GridView ID="gvAppeals" runat="server" DataKeyNames="App_no" >
I am facing difficulties when trying to get values from a cell in a gridview. Whenever I ask for the value it goes to NullExcaption, so I asked if the row itself is null, and it is. Here is the ASP code:
<asp:SqlDataSource ID="SqlDataSourceFlats" runat="server" ConnectionString="<%$ ConnectionStrings:EflatsConnectionString %>" SelectCommand="SELECT [Rent], [Address], [FlatId] FROM [Flat_Main]"></asp:SqlDataSource>
<asp:GridView ID="GridView1" onrowcommand="GridView1_RowCommand" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" CellPadding="4" DataKeyNames="FlatId" DataSourceID="SqlDataSourceFlats" ForeColor="#333333" GridLines="None" Width="100%" >
<AlternatingRowStyle BackColor="White" />
<Columns>
<asp:BoundField DataField="FlatId" HeaderText="FlatId" InsertVisible="False" ReadOnly="True" SortExpression="FlatId" />
<asp:BoundField DataField="Rent" HeaderText="Rent" SortExpression="Rent" />
<asp:BoundField DataField="Address" HeaderText="Address" SortExpression="Address">
<ControlStyle Width="60%" />
</asp:BoundField>
<asp:ButtonField Text="Add" CommandName="Apply" ButtonType="Button" />
<asp:ButtonField Text="Remove" ButtonType="Button" />
</Columns>
<EditRowStyle BackColor="#7C6F57" />
<FooterStyle BackColor="#1C5E55" Font-Bold="True" ForeColor="White" />
<HeaderStyle BackColor="#1C5E55" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#666666" ForeColor="White" HorizontalAlign="Center" />
<RowStyle BackColor="#E3EAEB" />
<SelectedRowStyle BackColor="#C5BBAF" Font-Bold="True" ForeColor="#333333" />
<SortedAscendingCellStyle BackColor="#F8FAFA" />
<SortedAscendingHeaderStyle BackColor="#246B61" />
<SortedDescendingCellStyle BackColor="#D4DFE1" />
<SortedDescendingHeaderStyle BackColor="#15524A" />
</asp:GridView>
And the button code:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Apply")
{
// string c = GridView1.Rows[e.NewEditIndex].Cells[2].Text;
// Response.Write(GridView1.SelectedRow.Cells[2].Text);
if (GridView1.SelectedRow == null)
{
Response.Write("Gridview is failing me :(");
}
// string celltext = this.GridView1.SelectedRow.Cells[2].Text;
// Response.Write(celltext);
}
}
Basically I want to click the button and get the FlatId value from the selected row.
The OnRowCommand event seems to have few mistakes.
1.) GridView1.SelectedRow::
you haven't actually selected any row, therefore this will always be null
2.) GridView1.Rows[e.NewEditIndex]::
Again, you are NOT editing any row, so what do you expect the value will be for e.NewEditIndex ?
How to Handle ButtonField events in the GridView control
Set the button's CommandName property to a string that identifies its function, such as "Select" , "Edit" etc...
To determine the index of the record, the RowIndex, use the CommandArgument property of the event argument that is passed to the command event for the data-bound control. The ButtonField class automatically populates the CommandArgument property with the appropriate row-index value.
Below is an example for selecting a record and Handling the OnRowCommand event:
Markup:
<columns>
<asp:buttonfield buttontype="Button" commandname="Select"
headertext="Select This Record" text="Select"/>
</columns>
and the OnRowCommand event:
void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
if(e.CommandName=="Select")
{
// Convert the row index stored in the CommandArgument
// property to an Integer.
int _rowIndex = Convert.ToInt32(e.CommandArgument);
GridViewRow selectedRow = CustomersGridView.Rows[_rowIndex];
string cellText = selectedRow.Cells[2].Text;
}
}
I display customers past orders in a gridview. They can press the Resend button in the last column to resend their order under the condition that the order is paid or past that status.
First the gridview:
<asp:GridView ID="GridView1" runat="server" AllowPaging="True" AllowSorting="True" AutoGenerateColumns="False" BackColor="White" pagesize="10"
BorderColor="#999999" BorderStyle="None" BorderWidth="1px" CellPadding="3" DataSourceID="SqlDataSource1" EmptyDataText="You have no orders yet"
GridLines="Vertical" OnRowCommand="GridView1_RowCommand">
<AlternatingRowStyle BackColor="#DCDCDC"/>
<Columns>
<asp:BoundField DataField="TD_OrdID" HeaderText="Ord" InsertVisible="False" ReadOnly="True" SortExpression="TD_OrdID" />
<asp:BoundField DataField="TD_OrdDate" DataFormatString="{0:d}" ItemStyle-HorizontalAlign="Right" HeaderText="Date" SortExpression="TD_OrdDate" ><ItemStyle HorizontalAlign="Right"></ItemStyle></asp:BoundField>
<asp:BoundField DataField="TD_PD_PackageName" HeaderText="Package Name" ItemStyle-HorizontalAlign="Left" SortExpression="TD_PD_PackageName" > </asp:BoundField>
<asp:BoundField DataField="TD_OSName" ItemStyle-HorizontalAlign="Right" HeaderText="Status" SortExpression="TD_OSName" > <ItemStyle HorizontalAlign="Right"></ItemStyle></asp:BoundField>
<asp:BoundField DataField="TD_InvID" HeaderText="Inv" InsertVisible="False" ReadOnly="True" SortExpression="TD_InvID" />
<asp:BoundField DataField="TD_InvPaid" HeaderText="Paid" ItemStyle-HorizontalAlign="Right" SortExpression="TD_InvPaid" ><ItemStyle HorizontalAlign="Right"></ItemStyle></asp:BoundField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button runat="server" ID="btnResend" CommandName="Resend" Text="Resend" CommandArgument="<% ((GridViewRow) Container).RowIndex
%>" OnDataBinding="btnResend_DataBinding" />
</ItemTemplate>
</asp:TemplateField>
</Columns>
<FooterStyle BackColor="#CCCCCC" ForeColor="Black" />
<HeaderStyle BackColor="#000084" Font-Bold="True" ForeColor="White" />
<PagerStyle BackColor="#999999" ForeColor="Black" HorizontalAlign="Center" />
<RowStyle BackColor="#EEEEEE" ForeColor="Black" Font-Size="Small" HorizontalAlign="Center"/>
<SelectedRowStyle BackColor="#008A8C" Font-Bold="True" ForeColor="White" />
<SortedAscendingCellStyle BackColor="#F1F1F1" />
<SortedAscendingHeaderStyle BackColor="#0000A9" />
<SortedDescendingCellStyle BackColor="#CAC9C9" />
<SortedDescendingHeaderStyle BackColor="#000065" />
</asp:GridView>
now the databinding to select the resend button when customer paid the order:
protected void btnResend_DataBinding(object sender, EventArgs e)
{
// only set button to enable when customer can resend document!
Button btn = (Button)(sender);
// enable button for status emailed, paid and closed
btn.Enabled = ((Eval("TD_OSName").ToString().Equals("closed")) ||
(Eval("TD_OSName").ToString().Equals("paid")) ||
(Eval("TD_OSName").ToString().Equals("emailed")));
}
which works fine. I am disabling the button. Maybe a better solution is to hide it instead. However this is not my concern.
now the row command to get the "ordId" value from the row where the button is pressed:
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Resend")
{
// Retrieve the row index stored in the
// CommandArgument Property
int index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button
// from Rows collection.
GridViewRow row = GridView1.Rows[index];
// add code
int ordId = Convert.ToInt32(row.Cells[0].Text);
lblMessage.ForeColor = System.Drawing.Color.Green;
//lblMessage.Text = displayMessages.YourDocumentResent() + "OrdID:" + ordId;
//lblMessage.Text = displayMessages.YourDocumentResent();
lblMessage.Text = Convert.ToString(e.CommandArgument);
}
}
However to get the selected row and reading out the order identification from the row is challenging for me. I goggled this over and over and can’t see where I make the mistake.
The line:
int index = Convert.ToInt32(e.CommandArgument)
fails with
Input string was not in a correct format
If found this even on the msdn page of Microsoft?!
If I display the e.commandArgument I see: <% ((GridViewRow) Container).RowIndex %>
Can anyone help so I can get the value OrdId from TD_OrdID from the row the customer has pressed the Resend button?
Thank you in advance.
<% ((GridViewRow) Container).RowIndex %>
You're missing the #.
Try:
<%# ((GridViewRow) Container).RowIndex %>