Get ListView item when button in row is clicked - c#

I have a ListView that creates a table. Each row in the table has two buttons - Delete and Modify. I'm firing a click event for each button but I'm not sure how to get a handle to the data in the row that the button was clicked.
aspx
<asp:ListView runat="server" ID="usersListView">
<LayoutTemplate>
<table class="table table-striped">
<thead>
<tr>
<th>User Name</th>
<th>Email</th>
<th>Role</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
<asp:PlaceHolder runat="server" ID="groupPlaceHolder"/>
</tbody>
</table>
</LayoutTemplate>
<GroupTemplate>
<tr>
<asp:PlaceHolder runat="server" ID="itemPlaceHolder"/>
</tr>
</GroupTemplate>
<ItemTemplate>
<td><%# Eval("user.UserName") %></td>
<td><%# Eval("user.Email") %></td>
<td><%# Eval("roles") %></td>
<td>
<button runat="server" id="modify" class="btn btn-mini" title="Modify" onclick="modify_OnClick">
<i class="icon-edit"></i>
</button>
<button runat="server" id="delete" class="btn btn-mini" title="Delete" onclick="delete_OnClick">
<i class="icon-trash"></i>
</button>
</td>
</ItemTemplate>
</asp:ListView>
aspx.cs
public void delete_Onclick(object sender, EventArgs e) {
}
public void modify_Onclick(object sender, EventArgs e) {
}

I will try to answer the question in the title since i don't understand the question itself.
You can cast the the sender to the Button. The Button's NamingContainer is the ListViewItem. You can use this to get all your other control in that item by using item.FindControl("OtherControlID").
For example;
public void delete_Onclick(object sender, EventArgs e) {
var btn = (Button)sender;
var item = (ListViewItem)btn.NamingContainer;
// find other controls:
var btnModify = (Button)item.FindControl("modify");
}
You cannot find text that is not in a server control. But you could use a LiteralControl or Label to display the username or email.
<td><asp:Label id="Label1" runat="server"
Text='<%# Eval("user.UserName") %>' />
</td>
Now you can use FindControl as shown above to get a reference to the label in codebehind.

I know 2 solutions:
1-command name and command argument as below
2-you can use links instead of buttons and send queryString that include
the id of your record to the same page u are,and take querystring in
code behind(page load) and use it for delete sqlcommadns or redirect it to another page for
editing purposes and finally Response.Redirect() again to the same page that you are.

You should be using a GridView since the data is tabular. At any rate, you can implement the ItemCommand event. The MSDN page has an example.
You can customize CommandName and the CommandArgument properties of an Button control. The CommandArgument can be made to contain some ID or a relevant piece of information.

Related

ASP.NET cannot access asp element from code behind (User Control)

I'm experiencing some trouble accessing the value of an asp element from code behind.
Basically, In my .ascx file I have a repeater and a data source. The repeater puts data from the data source (which is a database) into an HTML table like so:
<asp:Repeater ID="Repeater2" runat="server" DataSourceID="SqlDataSource1">
<HeaderTemplate>
<table id="VersionsTable">
</HeaderTemplate>
<ItemTemplate>
<thead>
<tr>
<th id="id">ID</th>
<th id="date">Date</th>
<th id="name">Name</th>
<th id="message">Message</th>
<th id="delete">Delete</th>
</tr>
</thead>
<tbody>
<tr>
<td> <asp:TextBox ID="idfield" runat="server" value='<%# Eval("LeaveAMessageID") %>' /></td>
<td id="idfield1"><%# Eval("LeaveAMessageID") %></td>
<td id="datefield"><%# Eval("FormInserted") %></td>
<td id="namefield"><%# Eval("TextBoxControl") %></td>
<td id="messagefield"><%# Eval("TextAreaControl") %></td>
<td id="deletebutton"><asp:Button id="Button1" Text="Delete Message" onclick="Button1_Click"
runat="server"> </asp:Button></td>
</tr>
</tbody>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Now, what i need to be able to do is to delete a table row from the database based on the value in the textbox with the id "idfield".
So when the button in the last column is clicked, the record will be deleted from the database.
The repeater and the table works as expected, they produce the output that i want. However, i can't seem to access the asp:textbox element from the code behind file.
My Button1_Click method looks like this:
public void Button1_Click(object sender, EventArgs e)
{
try
{
//TextBox f = (TextBox)this.FindControl("idfield");
//var msgID = /*Request.Form["idfield"];idfield.Value;*/Request["idfield"];
//var msgID = Request.QueryString["idfield"];
//var msgID = DataBinder.Eval(this, "idfield");
var control = (WebUserControl2)LoadControl("~/Controls/WebUserControl2.ascx");
var msgID = control.Repeater2.FindControl("idfield");
//var msgID = this.FindControl("Repeater2", 0).FindControl("idfield", 0);
//Connect to database
After this section of code follows the database connection and the execution of the SQL statement. Everything that you see outcommented in the code section above is the things I have tried to access the value of that asp:TextBox element, and with no success so far.
So my question is: How do i access the asp:TextBox element from code behind?
Not exactly what you asked but I think this is what you are looking for. Buttons have a CommandArgument property which can be used to store the id of the record you want to delete. This can be added to your button like so:
<asp:Button id="Button1" Text="Delete Message" onclick="Button1_Click"
runat="server" CommandArgument="<%# Eval("LeaveAMessageID") %>">
And can then be accessed from you click event like so:
public void Button1_Click(object sender, EventArgs e)
{
var id = ((Button)sender).CommandArgument;

How to access Listview items to codebehind using asp.net

Iam using a listview to display table contents,How can i access a values form listview to code behind in button click
aspx
<LayoutTemplate>
<table runat="server" id="table1">
<tr id="Tr1" runat="server">
<th class="tablehead"id="mname">Movie Name</th>
<th class="tablehead">Movie Genre</th>
<th class="tablehead">Runtime</th>
</tr>
<tr runat="server" id="itemPlaceholder"></tr>
<ItemTemplate>
<tr id="Tr2" runat="server" class="tablerw">
<td style="background-color:#EEEEEE;width:100px;" class="tablerw"><asp:Label ID="Label5" runat="server" Text='<%#Eval("MovieName") %>' /></td>
<td style="background-color:#EEEEEE;width:100px;"><asp:Label ID="NameLabel" runat="server" Text='<%#Eval("movieGenre") %>' /></td>
<td style="background-color:#EEEEEE;width:100px;"><asp:Label ID="Label1" runat="server" Text='<%#Eval("Runtime") %>' /></td>
<td>
<asp:Button ID="Button1" runat="server" Text="Approve" OnClick="Button1_Click"></asp:Button>//Here is my button
</ItemTemplate>
aspx.cs
protected void Button1_Click(Object sender,
System.EventArgs e)
{
//I want to access value here
}
I want to get Movie Name,Movie Genre,Runtime to code behind.. Any help is appreciated..
Proper way to deal with button control click event in data bound controls is by setting a CommandArgument & CommandName properties. Instead of registering a click handler of button you can register a ItemCommand event of ListView. This way whenever a button is clicked then this event is raised and you can find the data correctly like this:-
Add CommandName & CommandArgument properties to your button and remove the click handler:-
<asp:Button ID="Button1" runat="server" Text="Approve" CommandName="GetData"
CommandArgument='<%# Eval("MovieId") %>' ></asp:Button>
Next, register the ItemCommand event with your listview:-
<asp:ListView ID="lstMovies" runat="server" OnItemCommand="ListView1_ItemCommand">
Finally in the code behind, in ListView1_ItemCommand method check if event is raised by your button and find all the respective controls:-
protected void ListView1_ItemCommand(object sender, ListViewCommandEventArgs e)
{
if (e.CommandName == "GetData")
{
if (e.CommandSource is Button)
{
ListViewDataItem item = (e.CommandSource as Button).NamingContainer
as ListViewDataItem;
Label NameLabel = item.FindControl("NameLabel") as Label;
Label Label5 = item.FindControl("Label5") as Label;
//and so on..
}
}
}

Dynamic Link Button OnClick event not firing

I am creating several dynamic asp:Panels in asp:Lisview ItemTemplate. In panel there's a HTML table which is surrounded by link so the whole div/box is clickable. The problem is the linkbutton's OnClick event is not firing on server side. Any thoughts?
Here is the code:
<asp:Panel runat="server" ClientIDMode="Static">
<asp:LinkButton runat="server" ID="Link" OnClick="Link_Click" CausesValidation="false">
<table runat="server" id="Table" >
<thead>
<tr><th colspan="3"><%#Eval("abc")%></th></tr>
</thead>
<tbody>
<tr>
<td >
<asp:ImageButton runat="server" ImageUrl="../Images/img_4.png"/>
</td>
<td runat="server" class="data" >
<%#Eval("abc")%>
</td>
<td>
04:15
</td>
</tr>
</tbody>
</table>
</asp:LinkButton>
</asp:Panel>
LinkClick Code
protected void Link_Click(object sender, EventArgs e)
{
LinkButton link = (LinkButton)sender;
String id = link.ID;
if (id.StartsWith("T"))
Response.Redirect("Time.aspx?Id=" + id);
else
{
Response.Redirect("Chart.aspx?Id=" + id);
}
}
I figured it out. The asp:linkbutton id was being reset in the backend code and it was leading to broken link. That's why the click wouldn't work.

c# asp Repeater data not showing when using ItemDataBound to create a button based on field

basically i am trying to populate a departments table and based on, say the change date, create a button for whatever departments fall within a certain date range. Problem is, the button creates but there is no data,
heres what i have so far - onPageLoad i bind the datasource which all works and displays until i try iTemDataBound
ASP.net
<asp:Repeater ID="DepartmentsList" runat="server" OnItemDataBound="DepartmentsList_ItemDataBound"/>
<HeaderTemplate>
<table id="grouptable" class="table table-bordered table-striped">
<thead>
<tr>
<th>Send</th>
<th>ID</th>
<th>Name</th>
<th>Last Modified</th>
<th>Actions</th>
</tr>
</thead>
<tbody>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td>
<input type="checkbox" name="SendSelect[]" value="<%# Eval("Dept_ID") %>"</input></td>
<td><%# Eval("Dept_ID") %></td>
<td><%# Eval("DESC") %> </td>
<td><asp:Label ID="chg_date" runat="server" Text='<%# Eval("chg_date") %>'></asp:Label></td>
<td><a class="btn btn-info" href="<%# Eval("gURL") %>"><i class="icon-pencil icon-white"></i> Edit </a> &nbsp<asp:Button ID="bcastBtn" runat="server" Text="Send Now" CssClass="btn btn-danger" /> </td>
</tr>
</ItemTemplate>
<FooterTemplate>
</tbody>
</table>
</FooterTemplate>
</asp:Repeater>
c# code
protected void DepartmentsList_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
RepeaterItem item = e.Item;
if (e.Item.ItemType != ListItemType.Item && e.Item.ItemType != ListItemType.AlternatingItem)
{
return;
}
else
{
Repeater bcastbuttonControl = (Repeater)item.FindControl("bcastBtn");
Repeater DepartmentsList = (Repeater)item.FindControl("chg_date");
//Coding for date validation to go here - at the minute just checking based on empty or null
if (String.IsNullOrEmpty(chg_date.Text))
{
bcastBtn.Visible = false;
}
else
{
bcastBtn.Visible = true;
}
}
}
Repeater bcastbuttonControl = (Repeater)item.FindControl("bcastBtn");
Repeater DepartmentsList = (Repeater)item.FindControl("chg_date");
I think there's a problem with the above code. You should be casting the first to a button and the second to a textbox (or whatever control it is but it sure is not a repeater) your data might be disappering when you add the onitemdatabound because of an invalid cast exception here
RepeaterItem item = e.Item;
remove the above code and instead simply use:
Label chg_date = (Label)e.Item.FindControl("chg_date");
and if that doesn't work either can you post your page_Load code?

Use repeater to display all the threads in same topic question

I want to use asp.net repeater control to display all threads that under same topic. Each thread has three buttons--reply,edit and delete. Besides buttons, I also want to display author, subject, post time and content. I have two questions here regarding to how to write button click event and binding data to a div in backend. My front end code is as following:(I use c#)
<asp:Repeater ID="Repeater1" runat="server">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td colspan="2">
<asp:Button ID="btn_Reply" runat="server" Text="Rreply" OnClick="btn_Reply_Click" />
<asp:Button ID="btn_Edit" runat="server" Text="Edit" OnClick="btn_Edit_Click" CommandArgument='<%Eval("id").ToString() %>' />
<asp:Button ID="btn_Delete" runat="server" Text="Delete" OnClick="btn_Delete_Click" CommandArgument='<%Eval("id").ToString() %>' />
</td>
</tr>
<tr>
<td align="right" width="100px">Author:</td>
<td><%#Eval("owner") %></td>
</tr>
<tr>
<td align="right" width="100px">Subject:</td>
<td><%#Eval("title") %></td>
</tr>
<tr>
<td align="right" width="100px">Post Time:</td>
<td><%#Eval("timePosted") %></td>
</tr>
<tr>
<td colspan="2">
<div id="contentDiv" runat="server" ondatabinding="contentDiv_DataBinding"></div>
</td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</asp:Repeater>
Question 1: how to write button click event in backend, for example I want to use CommandArgument of edit button, what's the click event should be?
protected void btn_Edit_Click(object sender,??//I don't know how to write the second)
Question 2: the content stored in database is in html format, What to write in contentDiv_DataBinding event?
protected void contentDiv_DataBinding(object sender, System.EventArgs e)
{
//seems it can not find contentDiv, otherwise, I'll just use contentDiv.html=<%#Eval("content") %>
}
Thank you in advance!
As the control is nested inside the Repeater, you must refer to it by finding it inside the item being data bound:
protected void Repeater_DataBinding(object sender, System.EventArgs e)
{
HtmlControl contentDiv = e.item.FindControl("contentDiv");
}
However, I think it would be better to put a Literal control inside the Div and refer to that instead:
<div id="contentDiv" runat="server">
<asp:literal id="ltlContent" runat="server" />
</div>
protected void Repeater_DataBinding(object sender, System.EventArgs e)
{
Literal ltlContent = e.item.FindControl("ltlContent");
ltlContent = e.Item.DataItem("content");
}
Regarding controlling the buttons inside the Repeater, you can add a CommandName to the button and call this in the ItemCommand event:
<asp:Button ID="btn_Reply" runat="server" Text="Rreply" CommandName="Reply" CommandArgument='<%Eval("id")%>' />
<asp:Button ID="btn_Edit" runat="server" Text="Edit" CommandName="Edit" CommandArgument='<%Eval("id").ToString() %>' />
<asp:Button ID="btn_Delete" runat="server" Text="Delete" CommandName="Delete" CommandArgument='<%Eval("id").ToString() %>' />
protected void contentDiv_ItemCommand(object sender, System.EventArgs e)
{
if (e.CommandName == "Reply"){
}
if (e.CommandName == "Edit"){
}
if (e.CommandName == "Delete"){
}
}
Finally, change your Repeater tag to:
<asp:Repeater ID="Repeater1" runat="server" OnItemDataBound="Repeater_DataBinding" OnItemCommand="contentDiv_ItemCommand">

Categories

Resources