Finding in which row a Button was clicked in a GridView/Repeater - asp.net

I am binding a Repeater. Each row (is that the right word?) in the Repeater has a Button and a HiddenField. How do I determine the Value of the HiddenField based on which Button was clicked?
Code behind for Button's OnClick event:
protected void btnButton1_Click(object sender, EventArgs e)
{
Button btnButton1 = (Button)sender;
// how do i get this row's HiddenField Value?
}
edit: the CommandArgument suggestion from Pleun works but I am still having issues. I need to find the row(?) in the Repeater that the Button belongs to as there is also a TextBox in each row and I would need its value. So ideally I want to get that row and go FindControl("TextBox1") etc etc. Sorry, should have stated that in my initial question

What I like to do is add a CommandArgument to the button. In this code its an imagebutton but the idea is the same. So also no need for an extra hidden field.
<asp:ImageButton ID="btnMail" ImageUrl="~/imgnew/prof/sendlink.png"
CommandArgument='<%# Eval("id")%>'
And in the _Click event do
string id = ((ImageButton)sender).CommandArgument;
Update:
If you need all the data, you need a different event. The data in the repeater is available as Item in
RepeaterCommandEventArgs
in the Command event (RepeaterCommandEventArgs)
for handling the Command event see this example
http://www.asp.net/data-access/tutorials/custom-buttons-in-the-datalist-and-repeater-cs
or
http://msdn.microsoft.com/en-us/library/system.web.ui.webcontrols.repeatercommandeventargs.aspx

If you using Repeater you can identify elements in each row in the ItemDataBound.
If you using gridview use RowDataBound
Hope this helps

You can traverse upwards by getting the button's Parent, then doing a FindControl() on that control.
Row parentRow = (Row)((Button)sender).Parent;
var tBox = (System.Web.UI.WebControls.TextBox)parentRow.FindControl("myTextBox")
You may have to play around to see how deep the button is nested and with what control types to get to the appropriate parent.

My markup code:
<asp:Repeater ID="RptFiles" runat="server">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>--</td>
<td><%#Eval("title")%></td>
<td>
<asp:FileUpload ID="fuVersion" runat="server" />
<asp:Button ID="btnUploadVersion" Text="Last opp" runat="server" OnClick="btnUploadVersion_Click" CommandArgument='<%#Eval("Id") %>' />
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
My code behind
protected void Upload_Click(object sender, EventArgs e)
{
Button btn = (Button)sender;
var documentId = btn.CommandArgument;
//Get the Repeater Item reference
RepeaterItem item = btn.NamingContainer as RepeaterItem;
var fuVersion = (FileUpload)item.FindControl("fuVersion");
var filename = fuVersion.PostedFile.FileName
}

Related

select data from gridview field and populate textbox

I'm trying to populate a single text box (or parameter) with data from a gridview column when I click on a button in that row.
Gridview gets it data from a sqlconnection
the gridview is
| Drawing |
| 12345 | VIEW
| 12346 | VIEW
the VIEW is a template button with an onclick event, when the user clicks the button the data from the Drawing column (12345) should be passed to ether a textbox or a paremeter. (this is the part I dont know how to do) once the Iv got the number in a textbox I can use it as pareameter and then a pdf is opened of that drawing, I have code for this and is working.
thanks for any help
If you are using C#, the simplest thing to do would be to add an in-built select command button to the gridview rows at runtime. Then on the selectedindexchanged event of the gridview simply access the cell of the selected row that you want the value from. You can then assign that string to anything you want. Like so:
protected void myGridView_SelectedIndexChanged(object sender, EventArgs e)
{
string myString = myGridView.SelectedRow.Cells[4].Text.ToString();
TextBox1.Text = myString;
}
Remember that the cell index collection is zero based, so [0] is actually the first cell in the row.
Use TemplateFields and the grid view's OnRowCommand event, like this:
Markup:
<asp:gridview id="GridView1"
OnRowCommand="GridView1_RowCommand"
runat="server">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:TextBox ID="TextBoxDrawing" runat="server"
Text="<%# Eval("Drawing")) %>" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="selc" runat="server" Text="View"
CommandName="View"
CommandArgument="<%# ((GridViewRow)Container).RowIndex %> />
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Code-behind:
protected void GridView1_RowCommand(Object sender, GridViewCommandEventArgs e)
{
// If multiple buttons are used in a GridView control, use the
// CommandName property to determine which button was clicked
if(e.CommandName == "View")
{
// Convert the row index stored in the CommandArgument
// property to an integer
var index = Convert.ToInt32(e.CommandArgument);
// Retrieve the row that contains the button clicked
// by the user from the Rows collection
var row = GridView1.Rows[index];
// Find the drawing value
var theDrawingTextBox = row.FindControl("TextBoxDrawing") as TextBox;
// Verify the text box exists before we try to use it
if(theDrawingTextBox != null)
{
var theDrawingValue = theDrawingTextBox.Text;
// Do something here with drawing value
}
}
}

how to take value from grid view and stores into text box ,on a template button event?

I have created a form for saving Medium details, columns are, MID,MediumName,CreationDate,Status.I have bind full table in a gridview name gvmedium, i am having a textbox on the form .I want to fill the text box from grid views value of column MediumName on the template button click event.can any one help me?
You can use CommandName and Command Argument to achieve it and on Code Behind use RowCommand event.
<ItemTemplate>
<asp:LinkButton ID="lnkResetPassword" Text="Reset Password" runat="server" CommandName="ResetPassword" CommandArgument='<%# Bind("UserId") %>'></asp:LinkButton>
</ItemTemplate>
and then do your work here
protected void grdUserGroupList_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "ResetPassword")
{
GridViewRow gvr = (GridViewRow)(((LinkButton)e.CommandSource).NamingContainer);
int RowIndex = gvr.RowIndex;
lblMId.Text = e.CommandArgument.ToString();
txtMedium.Text=gvMedium.Rows[RowIndex ].Cells[0].Text;
}
}

How to capture a textchanged event when the textbox is inside a ListView?

I have a series of textbox in a listview which contain the hours and minutes for employees. I want values entered to be computed when any of the textboxes loses focus. I've tried this exemple from the MSDM. For button and LinkButton, I can use OnItemCommand, for DDl and listbox, I can use OnSelectedIndexChanged.
How about Textchanged for my texboxes? I don't see any event for them. From MSDN, the only method that resemble to that is TextBox.TextChanged Event. But it said on that page : "This API supports the .NET Framework infrastructure and is not intended to be used directly from your code."
The TextBoxes are in the ItemTemplate(or EditItemTemplate), aren't they? If they have AutoPostBack=true they'll post back as soon as the text changed and the focus lost. Just the same as outside of a ListView.
on aspx:
<ItemTemplate>
<tr runat="server">
<td>
<asp:TextBox OnTextChanged="TextBox1_TextChanged" AutoPostBack="true"
ID="Textbox1" runat="Server" Text="here is text" />
</td>
<td>
</tr>
</ItemTemplate>
in codebehind:
protected void TextBox1_TextChanged(object sender, EventArgs e)
{
TextBox TextBox1 = (TextBox) sender;
}

find control in listview

By pressing button in GridView i need to find control in Listview.
<ItemTemplate>
<td>
<asp:Label ID="lblMarketLVBalanceHeader" runat="server" Text="Balance: "></asp:Label>
</td>
<td>
<asp:Label ID="lblMarketLVBalanceValue" runat="server" Text='<%# Bind("Money", "{0:####}$") %>'></asp:Label>
</td>
</ItemTemplate>
Code Behind:
protected void GVMarketItems_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName.Equals("Buy"))
{ GridViewRow row = (GridViewRow)(((Button)e.CommandSource).NamingContainer);
/* string itemID = row.Cells[0].Text;
string itemName = row.Cells[1].Text;
string itemCostStr = row.Cells[3].Text; */
string curBalanceStr = ((Label)LVMarketBalanceShow.FindControl("lblMarketLVBalanceValue")).Text;
}
Code seems find, but i have "Object reference not set to an instance of an object" when i'm trying to Find control.
string curBalanceStr = ((Label)LVMarketBalanceShow.FindControl("lblMarketLVBalanceValue")).Text;
Did the same to DetailsView and it was Ok.. What's wrong with ListView?
UPD: Trying to get first fow of listview
ListViewDataItem curBalanceLV = LVMarketBalanceShow.Items[0];
string curBalanceStr =((Label)curBalanceLV.FindControl("lblMarketLVBalanceValue")).Text;
But getting an error "Index was out of range."
I think you want to find the control within the specific row.
string curBalanceStr = ((Label)row.FindControl("lblMarketLVBalanceValue")).Text
Did the same to DetailsView and it was Ok.. What's wrong with
ListView?
A DetailsView is used to tackle with one row at a time so you can directly call FindControl() on the detailsview but gridview and listview are meant to display multiple records and your markup you define inside <ItemTemplate /> is just a template for each row. You'll be able to find the controls that you define in the template inside of each row.

give the ID as a custom attribute to checkbox in a grid for manual update

I like to update just the value of my checkbox in a asp grid.
so i thought i bind the id to the checkbox ( but how?) and fire an update in code behind by clicking the checkbox.
but how can I get the ID, and where I have to bind this id to get it in code behind in the event?
Thanks
Here is what I've managed to do. (Be aware there should be an easier way to do this. I'm very new to ASP.NET)
Here you have a TemplateField in a GridView. Inside it there is an UpdatePanel and the CheckBox is inside it. This is done to make the checking of the TextBox do post in the backgroung (ajax). You might not need it (UpdatePanel) at all.
<asp:TemplateField HeaderText="Private" SortExpression="IsPrivate">
<ItemTemplate>
<asp:UpdatePanel ID="upIsPrivate" runat="server" UpdateMode="Always" ChildrenAsTriggers="true">
<ContentTemplate>
<asp:CheckBox ID="chkIsPrivate" runat="server" OnCheckedChanged="chkIsPrivate_CheckedChanged" AutoPostBack="true" />
</ContentTemplate>
</asp:UpdatePanel>
</ItemTemplate>
</asp:TemplateField>
And this is the method that handles this. Notice that I get the Id from the GridViewRow that contains the CheckBox:
GridViewRow row = (GridViewRow)((CheckBox)sender).Parent.Parent.Parent.Parent;
protected void chkIsPrivate_CheckedChanged(object sender, EventArgs e)
{
if (editMode)
{
GridViewRow row = (GridViewRow)((CheckBox)sender).Parent.Parent.Parent.Parent;
Int32 id = (Int32)uxPhoneCallList.DataKeys[row.RowIndex]["Id"];
CheckBox isPrivate = (CheckBox)row.FindControl("chkIsPrivate");
PhoneCall phoneCall = PhoneCallManager.GetById(id);
...
}
}

Resources