I have a control image in a user control. And I'm using a repeater to create several images list.
I have a button outside from the user control to delete image (per images).
I want to know, how can I make references to an specific row when I click in the button to delete the image.
This is the repetear:
<asp:Repeater ID="ImageRepeater" runat="server"
onitemcommand="ImageRepeater_ItemCommand">
<ItemTemplate>
<div>
<uc1:IVT_DisplayImage ID="IVT_DisplayImage1" runat="server" ImageURL="<%# Container.DataItem %>" />
<asp:Button ID="RemoveDiplayImage" Text="Remove" runat="server"
CommandName="delete"
/>
</div>
</ItemTemplate>
</asp:Repeater>
This is the event ItemCommand:
protected void ImageRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if (e.CommandName == "delete")
{
//????
}
}
I want to know, how identify by code wich row (user control) I'm selecting.
You need to add CommandArgument to your button like CommandArgument="<%# Container.ItemIndex %>".
This way, in the code; e.CommandArgument gives you the item number, with which you can get the item that you want.
Note: In fact instead of specifying ItemIndex as CommandArgument, you can use any Primary Key (Unique Identifier) from the DataSource that you bind to the repeater from where you will be able to get hold of the record directly from the list object (DataSource).
Related
I have a table with two columns and multiple rows, the first column has names and the second one has buttons, how can I get the name next to the button when I click any button.
The names will be taken from a database and the buttons will be generated from code behind depending on the number of names I have in my database.
Let's say that I have this:
<asp:table runat="server" id="table1">
<tr><td>Name1</td><td><asp:Button runat="server" Text="Save"/></td></tr>
<tr><td>Name2</td><td><asp:Button runat="server" Text="Save"/></td></tr>
<tr><td>Name3</td><td><asp:Button runat="server" Text="Save"/></td></tr>
</asp:table>
How can I know which name is next to the button, when I click any of them, I want to get the name so that I can save it in a database.
use for your designer code something similar to this:
<asp:GridView ID="GridView" runat="server" OnRowCommand="gvUsers_RowCommand" AutoGenerateColumns="True">
<Columns>
<asp:TemplateField>
<ItemTemplate>
<asp:LinkButton ID="detail_LB" runat="server" Text="Detail" CommandName="Detail_LB" CommandArgument="<%# ((GridViewRow) Container).RowIndex %>"></asp:LinkButton>
</ItemTemplate>
</asp:TemplateField>
</Columns>
</asp:GridView>
Notice the OnRowCommand and for the LinkButtons the CommandName and CommandArgument. The argument contains the row number, where you clicked the button.
In your code behind:
protected async void gvUsers_RowCommand(object sender, GridViewCommandEventArgs e)
{
if (e.CommandName == "Detail_LB")
{
//index contains the row number
int index = Convert.ToInt32(e.CommandArgument);
//get text in the cell next to the button
string text = gvUsers.Rows[index].Cells[0].Text;
}
}
If hope this helps you to understand how to work with tables.
In asp.net I have a table in database containing questions,date of submission and answers.On page load only questions appear.now i want to use any link which on clicking show answers and date specified in table data, either in textbox or label and clicking again on that link answer disappear again like expand and shrink on click.
So what coding should i use for this in C#?
I believe you could handle the ItemCommand event of the Repeater.
Place a LinkButton control for the link that you want the user to click in the Repeater's item template. Set the CommandName property of this to something meaningful, like "ShowAnswers". Also, add a Label or TextBox control into the Repeater's item template, but set their Visible property to false within the aspx markup.
In the code-behind, within the ItemCommand event handler check if the value of e.CommandName equals your command ("ShowAnswers"). If so, then find the Label or TextBox controls for the answers and date within that Repeater item (accessed via e.Item). When you find them, set their Visible property to true.
Note: you could take a different approach using AJAX to provide a more seamless experience for the user, but this way is probably simpler to implement initially.
I think the implementation would look something like this. Disclaimer: I haven't tested this code.
Code-Behind:
void Repeater_ItemCommand(Object Sender, RepeaterCommandEventArgs e)
{
if (e.CommandName == "ShowAnswers")
{
Control control;
control = e.Item.FindControl("Answers");
if (control != null)
control.Visible = true;
control = e.Item.FindControl("Date");
if (control != null)
control.Visible = true;
}
}
ASPX Markup:
<asp:Repeater id="Repeater" runat="server" OnItemCommand="Repeater_ItemCommand">
<ItemTemplate>
<asp:LinkButton id="ShowAnswers" runat="server" CommandName="ShowAnswers" />
<asp:Label id="Answers" runat="server" Text='<%# Eval("Answers") %>' Visible="false" />
<asp:Label id="Date" runat="server" Text='<%# Eval("Date") %>' Visible="false" />
</ItemTemplate>
</asp:Repeater>
What I'm trying to accomplish is when I click a button in my gridview, the values of that particular row must be displayed in textlabels lblID, lblName, ...
I just don't have a clue how to do it.
This is the code of my sqldatasource:
<asp:SqlDataSource ID="srcProd" runat="server"
ConnectionString="<%$ ConnectionStrings:ConnDB %>"
ProviderName="<%$ ConnectionStrings:ConnDB.ProviderName %>"
SelectCommand="SELECT p.tProdID, p.tProdImage, p.tProdBeschrijving, m.tMerkNaam, m.tMerkImage, p.tProdVerkoop FROM tblProducten AS p INNER JOIN tblMerken AS m ON p.tMerkID = m.tMerkID ORDER BY m.tMerkNaam">
</asp:SqlDataSource>
This is a screenshot of the gridview I'm talking about.
When I press one of the buttons I would like e.g. the parameter ID displayed in lblID.
All help, hints and tips are appreciated.
Assign a CommandName (which is like "ShowDetails" or so) and a CommandArgument (which is the ID of the record) to the button. A click on the button will now trigger the grid's RowCommand event, passing you both CommandName and CommandArgument in e. Then fetch the record from your DB and populate your controls:
<asp:TemplateField>
<ItemTemplate>
<asp:Button runat="server" Text="Foo2" CommandArgument='<%# Eval("RowID") %>'
CommandName="ShowDetails" />
</ItemTemplate>
</asp:TemplateField>
protected void GridView1_RowCommand(object sender, GridViewCommandEventArgs e)
{
Debug.WriteLine("Command Handler");
}
SO basicly this can be done on two ways:
Add a server-side click handler behind the button and update the label inside an UpdatePanel (this case we do not need a postback)
Add some javascript on the button's "OnClientClick" event to set this label... This method can be set in the GridView's bind method.
Hope this helps.
I have a DataList and inside of each item there is an ImageButton that needs to save the contents of an associated textarea. I normally would pass parameters using the CommandArgument tag, but the text inside the description is very long and I do not want to write it out into the commandargument for all the items being displayed. Instead, how can I find the ID of the associated textarea so I can save the text the user changes/enters?
I tried passing 'this' into the commandargument but I do not think it is working as it just passes the object for the button and not the whole item.
I realize this seems like a basic question but I've searched for over an hour. Your help is very appreciated.
<asp:ImageButton ID="saveDesc" runat="server" AlternateText="Save Image Description" BorderStyle="None" ImageUrl="..\..\images\save.png" CommandArgument='this' CommandName="SaveDescription" />
<asp:TextBox ID="description" runat="server" Text='<%#Eval("description")%>' style="font-weight:bold; width:100%" TextMode="MultiLine" Height="50px"/>
There are actually multiple DataLists inside of multiple Accordion views, but I'm not sure if this is relevant to the answer.
Thanks
You can do like...
protected void DataList1_ItemCommand(object source, DataListCommandEventArgs e)
{
if (e.CommandName == "SaveDescription")
{
DataListItem item = ((DataListItem)((ImageButton)e.CommandSource).NamingContainer);
TextBox description = (TextBox)item.FindControl("description");
description.Text // return your text
}
}
I have a nested Repeater control in the ItemTemplate of another Repeater. I want to dynamically add a delete and update button to certain items in the nested Repeater depending on their data value, in this case whether they're associated with the current user. A click to either button should handled server-side based so the data source can be updated, the nested repeater re-bound and an Update Panel that contains both repeaters would be updated.
<asp:Repeater ID="rpProCom" runat="server">
<HeaderTemplate><div class="comment"></HeaderTemplate>
<ItemTemplate>
<div class="c-score"><%# Eval("Text") %></div>
<asp:UpdatePanel ID="upOut" runat="server" ChildrenAsTriggers="true" UpdateMode="Always" >
<ContentTemplate>
<asp:Repeater ID="rpVotes" runat="server" DataSource='<%# ((ScoreBoard.Score)Container.DataItem).Votes %>' OnItemDataBound="rpVotes_ItemDataBound">
<HeaderTemplate><ul></HeaderTemplate>
<ItemTemplate>
<li>
<div class="c-ctrl"><asp:PlaceHolder ID="phD" runat="server" /></div>
<div class="c-box"><!-- placeholder for more tools --></div>
<div class="c-i"><div runat="server" ID="imgCom" class='<%# Eval("ImgClass") %>' /></div>
<div class="c-head">
<strong><%# Eval("UserName") %></strong>
<br /><%# Eval("Dt")%>
</div>
<div class="c-body"><%# Eval("Comment") %></div>
</li></ItemTemplate><FooterTemplate></ul></FooterTemplate>
</asp:Repeater>
</ContentTemplate></asp:UpdatePanel>
</ItemTemplate>
<FooterTemplate></div></FooterTemplate>
</asp:Repeater>
The outer repeater is bound in Page_Init
protected void rpVotes_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
if (e.Item.ItemType == ListItemType.Item || e.Item.ItemType == ListItemType.AlternatingItem) {
if (((Vote)e.Item.DataItem).UserName == user.UserName){
LinkButton btn = new LinkButton();
btn.Text = "delete";
btn.CommandName = "delCom";
btn.CommandArgument = ((Vote)e.Item.DataItem).ID.ToString();
btn.Click += new EventHandler(DeleteComment);
btn.ID = "d" + ((Vote)e.Item.DataItem).ID.ToString();
//find contrl
e.Item.FindControl("phD").Controls.Add(btn);
}
}
}
Since the Button is created on item databound and is nested within another control, I can't think of a reasonable way to persist the button and the unique identifier of the Data Item in Viewstate so I can recreate the button(s) on PageInit postback in order to fire the button's Click event.
I tried using Command Arguments, but they are empty:
javascript:__doPostBack('ctl00$CPHRight$rpProCom$ctl02$rpVotes$ctl01$d21','')
I need a reference to the containing Repeater and a unique identifier for the item in the repeater so I can update the DB and rebind that Repeater (ideally in an UpdatePanel that encompasses just that Repeater). I know this is a classic problem, and I'm sure someone's solved it.
So basically, is there some way to force a command argument into a dynamically control created dynamically during ItemDataBound or otherwise identify which dynamically created button caused postback? Can I put and Update Panel in a Repeater? Also can I possibly use the word dynamically again in this post?
You can use dynamically as much as you want :-)
What I would recommend is declaring a static button, adding an itemdatabound event, and showing/hiding the button instead by setting the Visible property of it; that way, you won't have to concern yourself with the reloading issues, but the user won't be able to see the buttons they don't have permissions for.
HTH.