I have a GridView with a TemplateField. Inside the ItemTemplate there are 2 TextBox's and then a <table> with an Panel. In that Panel there's another TextBox.
How do I get the value of that last TextBox?
I have the index of the gridview's row, but I don't know how to get on from there.
(Data from DB is bound at page load).
<asp:ScriptManager runat="server"></asp:ScriptManager>
<asp:GridView ID="grv_Four_Rows" runat="server" AutoGenerateColumns="False"
ShowHeader="False" CellPadding="3" CssClass="myGrid" DataKeyNames="Test1_First_Name">
<RowStyle BackColor="#b5c7de" />
<AlternatingRowStyle BackColor="#d1e0e0" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="txbFirstName" runat="server" CssClass="myTextBox" ReadOnly="false" Text='<%# Eval("Test1_First_Name")%>'></asp:TextBox>
<asp:TextBox ID="txbLastName" runat="server" CssClass="myTextBox" ReadOnly="true" Text='<%# Eval("Test1_Last_Name")%>'></asp:TextBox>
<table style="width: 350px;">
<asp:Panel ID="upp_2nd_row" runat="server" Visible="true">
<td style="float: left">
<a style="color: red; font-weight: bold;">Address: </a>
<asp:TextBox ID="txbAddress" Width="200px" Font-Bold="true" runat="server" Text='<%# Eval("Test1_Address")%>' />
</td>
<td style="float: right">
<asp:Button ID="btn_Edit_Details" runat="server" Text="Go" Font-Bold="true"
OnClick="my_Update_details" CommandArgument='<%#DataBinder.Eval(Container, "DataItemIndex")%>' />
</td>
</asp:Panel>
</table>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
<br />
<asp:Label ID="lblMessage1" runat="server" BackColor="Yellow" Font-Bold="true"></asp:Label>
C# Code behind:
protected void my_Update_details(object sender, EventArgs e)
{
string my_row_index = (sender as Button).CommandArgument;
lblMessage1.Text = "Row Index: " + my_row_index;
}
When I click the "Go" button in any row, the my_Update_details event is fired. All it does is, it displays the gridview's current row's index, and the value is correct.
But in the my_Update_details I also want to pick the values of the textbox's, and that's where I'm stuck (user is supposed to change their values and the 'Go' button should update the DB). In the following example I clicked the button in the 4th row and it correctly displays the index as 3 :
So this is how it works: first I rack my brains for a couple of days, then I post a question in SO, then - after 2 minutes I find a solution...
All I did was add a line in the my_Update_details method (the second line) :
protected void my_Update_details(object sender, EventArgs e)
{
string my_row_index = (sender as Button).CommandArgument;
TextBox AAAAAA = (TextBox)grv_Four_Rows.Rows[Convert.ToInt32(my_row_index)].Cells[0].FindControl("txbAddress");
lblMessage1.Text = "Address: " + AAAAAA.Text;
lblMessage2.Text = "Row Index: " + my_row_index;
}
and now I get:
which is exctly what I needed : to get the value that's in the txbAddress textbox.
Hope it will help someone in the future....
Related
I have a textbox in a datalist I'm trying to access in edit mode:
<asp:DataList ID="dl1" OnEditCommand="dl1_EditCommand"
OnCancelCommand="dl1_CancelCommand" OnUpdateCommand="dl1_UpdateCommand"
runat="server">
...
<asp:TextBox ID="tbType" Width="600" runat="server" Text='<%# Eval("Type") %>' />
CodeBehind:
protected void dl1_UpdateCommand(object sender, DataListCommandEventArgs e)
{
TextBox tb = (TextBox)e.Item.FindControl("tbType");
}
My code executes, but the value of the textbox is always empty, even though I have a value in it! I don't get either my updated text or the default text - I get a null. It finds the textbox, I've even opened the inspector to view its text...
This hasn't happened before and I'm not sure what I'm doing wrong. I've never had a problem like this before...
Full disclosure - this is a datalist inside a usercontrol.
UPDATE
Showing EditItemTemplate tags as requested.
The value is "" - I get a reference to the textbox, but no value.
<EditItemTemplate>
<td><asp:LinkButton ID="lbEdit" runat="server" Text="Update" CommandName="update" CausesValidation="false" />
<br /><asp:LinkButton ID="lbCancel" runat="server" Text="Cancel" CommandName="cancel" CausesValidation="false" />
</td>
<td>
<asp:HiddenField ID="hfID" runat="server" Value='<%# Eval("Id") %>' />
<asp:TextBox ID="tbType" Width="600" runat="server" Text='<%# Eval("Type") %>' />
</td>
<td></td>
</EditItemTemplate>
<div>
<table>
<tr>
<td>
<asp:Label runat="server" text="Search"></asp:Label>
</td>
<td>
<asp:TextBox runat="Server" placeholder="Enter EmpId" id="txtSearch">
</asp:TextBox>
</td>
<td>
<asp:Button ID="btnGo" runat="server" Text="Go" onclick="btnGo_Click"/>
</td>
<td>
<asp:Button ID="btnShowAll" runat="server" Text="ShowAll"
onclick="btnShowAll_Click" />
</td>
</tr>
</table>
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False">
<Columns>
<asp:BoundField HeaderText="EmpId" DataField="EmpId"/>
<asp:BoundField HeaderText="Employee Name" DataField="EmpName"/>
<asp:BoundField HeaderText="Designation" DataField="EmpDesgn"/>
<asp:BoundField HeaderText="Salary" DataField="Sal"/>
<asp:TemplateField HeaderText="Salary Status">
<ItemTemplate>
<asp:Button runat="Server" id="btnPay" text="Pay" CommandName="Pay"
Visible='<%#Eval("Status").Equals("Paid")?false:true %>' />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</div>
I want to pay the salary of unpaid employees on clicking the pay button as pay button is showing only for unpaid salaries.
You can do this using OnRowCommand event. Add the event handler to the gridview
OnRowCommand="GridView1_RowCommand"
Bind the command argument to your button
<asp:TemplateField HeaderText="Salary Status">
<ItemTemplate>
<asp:Button runat="Server" id="btnPay" text="Pay" CommandName="Pay"
Visible='<%#Eval("Status").Equals("Paid")?false:true %>'
CommandArgument = '<%#Eval("EmpId")%>'
/>
</ItemTemplate>
</asp:TemplateField>
Then in the RowCommand event you can catch the EmpId from the command argument, pay the salary and rebind the grid view
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
if(e.CommandName=="Pay")
{
// get the command argument.
string empId = e.CommandArgument as string;
//you code here to pay the salary
//ReBind Gridview to refresh
}
}
I have nested a Gridview2(child) and I want to get the checked rows on a button click.
When I try to access Gridview2 from button click event I am not able to do that. However, I can access the parent Gridview1.
Can somebody explain me how to get the Child Gridview's checked rows on button click.
Also, Button is a column header of child Gridview.
Here is my code.
<asp:GridView ID="GridView1" runat="server" AutoGenerateColumns="False"
BackColor="White" BorderColor="#E7E7FF" BorderStyle="None" BorderWidth="1px"
CellPadding="3" GridLines="Horizontal"
onrowdatabound="GridView1_RowDataBound" DataKeyNames="id1">
<AlternatingRowStyle BackColor="#F7F7F7" />
<Columns>
<asp:TemplateField>
<ItemTemplate>
<a href="javascript:collapseExpand('id1_<%# Eval("id1") %>');">
<img id="imageSubId_<%# Eval("id1") %>" alt="Click to show/hide orders" border="0"
src="Images/bullet_toggle_plus.jpg" /></a>
</ItemTemplate>
</asp:TemplateField>
<asp:BoundField DataField="id1" HeaderText="ID" />
<asp:TemplateField>
<ItemTemplate>
<tr>
<td colspan="100%">
<div id="rid1_<%# Eval("id1") %>" style="display: none; position: relative; left: 25px;">
<asp:GridView ID="GridView2" runat="server" AutoGenerateColumns="false" CellPadding="4" ForeColor="#333333"
GridLines="None" OnRowCommand="Gridview2_RowCommand">
<Columns>
<asp:BoundField DataField="fname" HeaderText="First Name" />
<asp:BoundField DataField="mname" HeaderText="Middle Name" />
<asp:BoundField DataField="lname" HeaderText="Last Name" />
<asp:TemplateField>
<ItemTemplate>
<asp:CheckBox ID="checkselect" runat="server" />
</ItemTemplate>
<HeaderTemplate>
<asp:Button ID="Button4" runat="server" Text="Remove" CommandName="Split" OnClick="Button4_Click" />
<ajaxToolkit:ModalPopupExtender ID="ModalPopupExtender1" runat="server" TargetControlID="Button4" PopupControlID="Panel1" CancelControlID="Button1">
</ajaxToolkit:ModalPopupExtender>
</HeaderTemplate>
</asp:TemplateField> </Columns></asp:GridView>
</div>
</td>
</tr>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
What I'd do is add a CommandArgument to Button4's declaration that will allow me to find the related GridView2.
So, I'd use what you're using elsewhere, id1. Add CommandArgument='<%# Eval("id1") %>' to your Button4 declaration.
Now, in Button4_Click, you can cast the sender to a Button like so:
var button4 = (Button)sender;
Once you have button4 casted correctly to a Button, you can access the CommandArgument property.
var id1 = button4.CommandArgument;
Once you have id1, it's as simple as iterating through the parent GridView, GridView1. Looks like your second column is bound to id1 as well, so you'd do the following:
GridView foundGridView2;
foreach(GridViewRow gvr in GridView1.Rows)
{
if(gvr.RowType == DataControlRowType.DataRow && gvr.Cells[1].Text == id1)
{
foundGridView2 = gvr.FindControl("GridView2");
break; // Once we've found it, no need to iterate through other items
}
}
At this point, you now have access to your found GridView2, and you can iterate through the rows of GridView2 and check the checkboxes. Let me know if you need help doing that.
Adding to the answer because I think the parent GridView1 may be swallowing Button4's click:
Create an event handler for GridView1's OnRowCommand event.
In the resulting GridView1_RowCommand() method, use the following to handle JUST your Button4 Click event:
if(e.CommandName == "Split")
{
// At this point I would refactor out the code you put in Button4_Click
// into a separate method. I'll give you an example:
HandleButton4Click(e.CommandArgument); // e.CommandArgument will contain the id1
}
Let me get this straight. I manage to create a custom Gridview with a single checkbox but my problem here is that I want to include multiple dynamic Checkbox.
Here is my code:
<%# Control Language="C#" AutoEventWireup="true" EnableTheming="true" CodeFile="GridviewControl.ascx.cs" Inherits="UserControl_GridviewControl" %>
<link href="../Template/CSS/Style.css"type="text/css" rel="Stylesheet" />
<div>
<span id="Span5" style="font-family: Arial; font-size:12px;" ><asp:Label ID="lblCount" runat="server" Text="0" Font-Bold="true"></asp:Label>
Record/s</span>
<span class="maintenance-btns">
<asp:Button ID="btnNew" runat="server" Text=" New " onclick="btnNew_Click"/>
<asp:Button ID="btnDel" runat="server" Text=" Delete " onclick="btnDel_Click"/>
</span>
</div>
<asp:Panel ID="pnlPc" runat="server" CssClass="div-grid" ScrollBars="Auto">
<asp:GridView ID="gvListing" runat="server" AllowPaging="True" AutoGenerateSelectButton="true"
OnRowDataBound="gvListing_RowDataBound" skinid="gvListing"
onselectedindexchanged="gvListing_SelectedIndexChanged"
onpageindexchanging="gvListing_PageIndexChanging" PageSize="50" >
<FooterStyle CssClass="grid-footer" />
<Columns>
<asp:TemplateField HeaderText="CheckAll">
<HeaderTemplate>
<asp:CheckBox ID="chkSelectAll" runat="server" AutoPostBack="true"
OnCheckedChanged="chkSelectAll_CheckedChanged" CssClass="select-all"/>
</HeaderTemplate>
<ItemTemplate>
<asp:CheckBox ID="chkSelect" runat="server" AutoPostBack="true"
OnCheckedChanged="chkSelect_CheckedChanged" CssClass="listing-checkbox"/>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
</asp:Panel>
In this gridview I only have a checkboxes at the first column. I want to put the dynamically generated checkboxes at the last column.
P.S.: How do I retrieve the id with those dynamically create checkboxes?
You can do like this
protected void gvData_DataBound(object sender, EventArgs e)
{
foreach (GridViewRow objRow in gvData.Rows)
{
TableCell tcCheckCell = new TableCell();
var checkBox = new CheckBox();
checkBox.CheckedChanged += checkBox_CheckedChanged;
tcCheckCell.Controls.Add(checkBox);
objRow.Cells.AddAt(0, tcCheckCell);
}
}
void checkBox_CheckedChanged(object sender, EventArgs e)
{
//do something
}
I'm trying to get an ASP.NET 3.5 GridView to show a selected value as string when being displayed, and to show a DropDownList to allow me to pick a value from a given list of options when being edited. Seems simple enough?
My gridview looks like this (simplified):
<asp:GridView ID="grvSecondaryLocations" runat="server"
DataKeyNames="ID" OnInit="grvSecondaryLocations_Init"
OnRowCommand="grvSecondaryLocations_RowCommand"
OnRowCancelingEdit="grvSecondaryLocations_RowCancelingEdit"
OnRowDeleting="grvSecondaryLocations_RowDeleting"
OnRowEditing="grvSecondaryLocations_RowEditing"
OnRowUpdating="grvSecondaryLocations_RowUpdating" >
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:Label ID="lblPbxTypeCaption" runat="server"
Text='<%# Eval("PBXTypeCaptionValue") %>' />
</ItemTemplate>
<EditItemTemplate>
<asp:DropDownList ID="ddlPBXTypeNS" runat="server"
Width="200px"
DataTextField="CaptionValue"
DataValueField="OID" />
</EditItemTemplate>
</asp:TemplateField>
</asp:GridView>
The grid gets displayed OK when not in editing mode - the selected PBX type shows its value in the asp:Label control. No surprise there.
I load the list of values for the DropDownList into a local member called _pbxTypes in the OnLoad event of the form. I verified this - it works, the values are there.
Now my challenge is: when the grid goes into editing mode for a particular row, I need to bind the list of PBX's stored in _pbxTypes.
Simple enough, I thought - just grab the drop down list object in the RowEditing event and attach the list:
protected void grvSecondaryLocations_RowEditing(object sender, GridViewEditEventArgs e)
{
grvSecondaryLocations.EditIndex = e.NewEditIndex;
GridViewRow editingRow = grvSecondaryLocations.Rows[e.NewEditIndex];
DropDownList ddlPbx = (editingRow.FindControl("ddlPBXTypeNS") as DropDownList);
if (ddlPbx != null)
{
ddlPbx.DataSource = _pbxTypes;
ddlPbx.DataBind();
}
.... (more stuff)
}
Trouble is - I never get anything back from the FindControl call - seems like the ddlPBXTypeNS doesn't exist (or can't be found).
What am I missing?? Must be something really stupid.... but so far, all my Googling, reading up on GridView controls, and asking buddies hasn't helped.
Who can spot the missing link? ;-)
Quite easy... You're doing it wrong, because by that event the control is not there:
protected void gv_RowDataBound(object sender, GridViewRowEventArgs e)
{
if (e.Row.RowType == DataControlRowType.DataRow &&
(e.Row.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
{
// Here you will get the Control you need like:
DropDownList dl = (DropDownList)e.Row.FindControl("ddlPBXTypeNS");
}
}
That is, it will only be valid for a DataRow (the actually row with data), and if it's in Edit mode... because you only edit one row at a time. The e.Row.FindControl("ddlPBXTypeNS") will only find the control that you want.
I am using a ListView instead of a GridView in 3.5. When the user wants to edit I have set the selected item of the dropdown to the exising value of that column for the record. I am able to access the dropdown in the ItemDataBound event. Here's the code:
protected void listViewABC_ItemDataBound(object sender, ListViewItemEventArgs e)
{
// This stmt is used to execute the code only in case of edit
if (((ListView)(sender)).EditIndex != -1 && ((ListViewDataItem)(e.Item)).DisplayIndex == ((ListView)(sender)).EditIndex)
{
((DropDownList)(e.Item.FindControl("ddlXType"))).SelectedValue = ((MyClass)((ListViewDataItem)e.Item).DataItem).XTypeId.ToString();
((DropDownList)(e.Item.FindControl("ddlIType"))).SelectedValue = ((MyClass)((ListViewDataItem)e.Item).DataItem).ITypeId.ToString();
}
}
protected void grvSecondaryLocations_RowEditing(object sender, GridViewEditEventArgs e)
{
grvSecondaryLocations.EditIndex = e.NewEditIndex;
DropDownList ddlPbx = (DropDownList)(grvSecondaryLocations.Rows[grvSecondaryLocations.EditIndex].FindControl("ddlPBXTypeNS"));
if (ddlPbx != null)
{
ddlPbx.DataSource = _pbxTypes;
ddlPbx.DataBind();
}
.... (more stuff)
}
You can use SelectedValue:
<EditItemTemplate>
<asp:DropDownList ID="ddlPBXTypeNS"
runat="server"
Width="200px"
DataSourceID="YDS"
DataTextField="CaptionValue"
DataValueField="OID"
SelectedValue='<%# Bind("YourForeignKey") %>' />
<asp:YourDataSource ID="YDS" ...../>
</EditItemTemplate>
The checked answer from balexandre works great. But, it will create a problem if adapted to some other situations.
I used it to change the value of two label controls - lblEditModifiedBy and lblEditModifiedOn - when I was editing a row, so that the correct ModifiedBy and ModifiedOn would be saved to the db on 'Update'.
When I clicked the 'Update' button, in the RowUpdating event it showed the new values I entered in the OldValues list. I needed the true "old values" as Original_ values when updating the database. (There's an ObjectDataSource attached to the GridView.)
The fix to this is using balexandre's code, but in a modified form in the gv_DataBound event:
protected void gv_DataBound(object sender, EventArgs e)
{
foreach (GridViewRow gvr in gv.Rows)
{
if (gvr.RowType == DataControlRowType.DataRow && (gvr.RowState & DataControlRowState.Edit) == DataControlRowState.Edit)
{
// Here you will get the Control you need like:
((Label)gvr.FindControl("lblEditModifiedBy")).Text = Page.User.Identity.Name;
((Label)gvr.FindControl("lblEditModifiedOn")).Text = DateTime.Now.ToString();
}
}
}
<asp:GridView ID="GridView1" runat="server" PageSize="2" AutoGenerateColumns="false"
AllowPaging="true" BackColor="White" BorderColor="#CC9966" BorderStyle="None"
BorderWidth="1px" CellPadding="4" OnRowEditing="GridView1_RowEditing" OnRowUpdating="GridView1_RowUpdating"
OnPageIndexChanging="GridView1_PageIndexChanging" OnRowCancelingEdit="GridView1_RowCancelingEdit"
OnRowDeleting="GridView1_RowDeleting">
<FooterStyle BackColor="#FFFFCC" ForeColor="#330099" />
<RowStyle BackColor="White" ForeColor="#330099" />
<SelectedRowStyle BackColor="#FFCC66" Font-Bold="True" ForeColor="#663399" />
<PagerStyle BackColor="#FFFFCC" ForeColor="#330099" HorizontalAlign="Center" />
<HeaderStyle BackColor="#990000" Font-Bold="True" ForeColor="#FFFFCC" />
<Columns>
<asp:TemplateField HeaderText="SerialNo">
<ItemTemplate>
<%# Container .DataItemIndex+1 %>. 
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="RollNo">
<ItemTemplate>
<%--<asp:Label ID="lblrollno" runat="server" Text='<%#Eval ("RollNo")%>'></asp:Label>--%>
<asp:TextBox ID="txtrollno" runat="server" Text='<%#Eval ("RollNo")%>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="SName">
<ItemTemplate>
<%--<asp:Label ID="lblsname" runat="server" Text='<%#Eval("SName")%>'></asp:Label>--%>
<asp:TextBox ID="txtsname" runat="server" Text='<%#Eval("SName")%>'> </asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="C">
<ItemTemplate>
<%-- <asp:Label ID="lblc" runat="server" Text='<%#Eval ("C") %>'></asp:Label>--%>
<asp:TextBox ID="txtc" runat="server" Text='<%#Eval ("C") %>'></asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Cpp">
<ItemTemplate>
<%-- <asp:Label ID="lblcpp" runat="server" Text='<%#Eval ("Cpp")%>'></asp:Label>--%>
<asp:TextBox ID="txtcpp" runat="server" Text='<%#Eval ("Cpp")%>'> </asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Java">
<ItemTemplate>
<%-- <asp:Label ID="lbljava" runat="server" Text='<%#Eval ("Java")%>'> </asp:Label>--%>
<asp:TextBox ID="txtjava" runat="server" Text='<%#Eval ("Java")%>'> </asp:TextBox>
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField HeaderText="Edit" ShowHeader="False">
<EditItemTemplate>
<asp:LinkButton ID="lnkbtnUpdate" runat="server" CausesValidation="true" Text="Update"
CommandName="Update"></asp:LinkButton>
<asp:LinkButton ID="lnkbtnCancel" runat="server" CausesValidation="false" Text="Cancel"
CommandName="Cancel"></asp:LinkButton>
</EditItemTemplate>
<ItemTemplate>
<asp:LinkButton ID="btnEdit" runat="server" CausesValidation="false" CommandName="Edit"
Text="Edit"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
<asp:CommandField HeaderText="Delete" ShowDeleteButton="True" ShowHeader="True" />
<asp:CommandField HeaderText="Select" ShowSelectButton="True" ShowHeader="True" />
</Columns>
</asp:GridView>
<table>
<tr>
<td>
<asp:Label ID="lblrollno" runat="server" Text="RollNo"></asp:Label>
<asp:TextBox ID="txtrollno" runat="server"></asp:TextBox>
</td>
<td>
<asp:Label ID="lblsname" runat="server" Text="SName"></asp:Label>
<asp:TextBox ID="txtsname" runat="server"></asp:TextBox>
</td>
<td>
<asp:Label ID="lblc" runat="server" Text="C"></asp:Label>
<asp:TextBox ID="txtc" runat="server"></asp:TextBox>
</td>
<td>
<asp:Label ID="lblcpp" runat="server" Text="Cpp"></asp:Label>
<asp:TextBox ID="txtcpp" runat="server"></asp:TextBox>
</td>
<td>
<asp:Label ID="lbljava" runat="server" Text="Java"></asp:Label>
<asp:TextBox ID="txtjava" runat="server"></asp:TextBox>
</td>
</tr>
<tr>
<td>
<asp:Button ID="Submit" runat="server" Text="Submit" OnClick="Submit_Click" />
<asp:Button ID="Reset" runat="server" Text="Reset" OnClick="Reset_Click" />
</td>
</tr>
</table>