I am having trouble with a LinkButton firing the OnClick event where the LinkButton is in a nested repeater.
Here is my HTML Markup
<asp:Repeater ID="RepeaterGenres" runat="server" OnItemDataBound="LoadTitles">
<ItemTemplate>
<asp:HiddenField ID="hdnGenre" runat="server" Value='<%# DataBinder.Eval(Container.DataItem, "GenreID") %>' />
<%# DataBinder.Eval(Container.DataItem, "MovieGenre") %>
<asp:Repeater ID="RepeaterMovies" runat="server">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "MovieName") %>
<asp:LinkButton ID="lbMovieInfo" runat="server" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "MovieID") %>' OnClick="LoadMovieTitle">
Access Info
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
</ItemTemplate>
</asp:Repeater>
Here is my method to load the Genres. (have removed some of the declarations to simplify).
string sqlString = "SELECT * FROM Movies_Genres";
sqlCmd = new SqlCommand(sqlString, myConnection);
sqlReader = sqlCmd.ExecuteReader();
if (sqlReader.HasRows)
{
RepeaterGenres.DataSource = sqlReader;
RepeaterGenres.DataBind();
}
Here is my method to load the Movie Titles within each Genre.
protected void LoadTitles(object sender, RepeaterItemEventArgs args)
{
if (args.Item.ItemType == ListItemType.Item || args.Item.ItemType == ListItemType.AlternatingItem)
{
// Genre from HiddenField
HiddenField GenreID = (HiddenField)args.Item.FindControl("hdnGenre");
// Repeater
Repeater childRepeater = (Repeater)args.Item.FindControl("RepeaterMovies");
string sqlString = "SELECT * FROM Movies_Titles " +
"WHERE Genre = #Genre";
sqlCmd = new SqlCommand(sqlString, myConnection);
sqlCmd.Parameters.AddWithValue("#Genre", GenreID.Value);
sqlReader = sqlCmd.ExecuteReader();
if (sqlReader.HasRows)
{
childRepeater.DataSource = sqlReader;
childRepeater.DataBind();
}
else
{
childRepeater.DataSource = "";
childRepeater.DataBind();
}
}
}
Everything up to this point works fine. I get my Genre groups and within each Genre I get the movie titles that are flagged against that Genre, and also the Linkbutton against each movie title. It's the LinkButton that is NOT firing the OnClick event.
Here is the code i'm using for the OnClick event.
protected void LoadMovieTitle (Object sender, EventArgs e)
{
LinkButton linkb = (LinkButton)(sender);
string args = linkb.CommandArgument;
Response.Redirect("movieinfopage.aspx?id=" + args);
}
The solution I am hoping to get help with is what do I need to do in order for those LinkButtons to fire their OnClick event when clicked, and access LoadMovieTitle. When I put a break in this method, it does not break, telling me that the OnClick event is not finding or recognising it.
You need to add OnItemCommand to repeater and CommandName to LinkButton:
<asp:Repeater ID="RepeaterMovies" runat="server" OnItemCommand="RepeaterMovies_OnItemCommand">
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "MovieName") %>
<asp:LinkButton ID="lbMovieInfo" runat="server" CommandArgument='<%# DataBinder.Eval(Container.DataItem, "MovieID") %>' CommandName="MovieDetail">
Access Info
</asp:LinkButton>
</ItemTemplate>
</asp:Repeater>
Server side:
protected void RepeaterMovies_OnItemCommand(object sender, RepeaterCommandEventArgs e)
{
if (e.CommandName.Equals("MovieDetail"))
{
LinkButton linkb = (LinkButton)(sender);
string args = linkb.CommandArgument;
Response.Redirect("movieinfopage.aspx?id=" + args);
}
}
See:
https://learn.microsoft.com/en-us/aspnet/web-forms/overview/data-access/custom-button-actions-with-the-datalist-and-repeater/custom-buttons-in-the-datalist-and-repeater-cs
Related
Here is my part of Shop.aspx code:
<% foreach(var item in items){ %>
...
<asp:Button id="btnBuy" runat="server" class="btn" Text="Buy" OnClick ="btnBuy_Click" CommandArgument='<%#Eval("item.id") %>' />
<% } %>
I've got a loop where I create few buttons to my shopping items, and I need them to have id of my item
protected void btnBuy_Click(object sender, EventArgs e)
{
int itemId = Convert.ToInt32(btnBuy.CommandArgument);
}
On click i need to have id of the item/button clicked, to save them later in my database.
Problem -
When i click on button btnbuy.CommandArgument is "".
It's wrong: you wrote c#in asp style. You have to use a Repeater and then you can manage ItemCommand for every button click.
Aspx
<asp:Repeater ID="myRepeater" runat="server" OnItemCommand="myRepeater_ItemCommand">
<ItemTemplate>
<asp:Label id="myLbl" runat="server" Text='<%# ((Item)(Container.DataItem)).ProductName %>'/>
<asp:Button id="btnBuy" runat="server" CssClass="btn" Text="Buy" CommandName="Click" CommandArgument='<%# ((Item)(Container.DataItem)).ProductId %>' />
</ItemTemplate>
</asp:Repeater>
c# (eg. OnLoad)
List<Item> myCollection = ...; // get list of items
myRepeater.DataSource = myCollection;
myRepeater.DataBind();
...
protected void myRepeater_ItemCommand(Object sender, RepeaterCommandEventArgs e)
{
if(e.CommandName == "Click")
{
int idRecord = Convert.ToInt32(e.CommandArgument);
// do something using idRecord or
// get sender properties: ((Button)e.CommandSource).Text
}
}
I have a payment method repeater that contains a button. We have new button styles that need to be applied. The new button style changes based on a btnMode setting in the database which is set to a string representing a CSS class selector. The CSS works fine.
I put this in the ASPX page:
<asp:Button ID="btnEdit"
runat="server"
ClientIDMode="Static"
CssClass='<%# Eval("btnMode") %>'
Text="edit"
CommandName="ChangePaymentProfile"
CommandArgument='<%# Eval("PaymentSourceId") + "|" + Eval("AuthNetPaymentProfileId")%>' />
In the ASPX.cs
//Command Button Clicked: Change Payment Method
else if (e.CommandName.ToLower().Equals("changepaymentprofile"))
{
hdChangeYN.Value = "Y";
showAddPaymentForm();
//display billing address of selected card
hsParams.Add("CustomerId", User.Identity.Name);
hsParams.Add("PaymentSourceId", strPaymentSourceId);
DataTable dt = DbHelper.GetDataTableSp("234_accountAddress__ByPaySourceId", hsParams);
if (dt.Rows.Count > 0)
{
tbFistName.Text = dt.Rows[0]["FirstName"].ToObjectString();
tbLastName.Text = dt.Rows[0]["LastName"].ToObjectString();
inputAddress1.Text = dt.Rows[0]["Address"].ToObjectString();
inputAddress2.Text = "";
string strCountryCd = dt.Rows[0]["CountryCd"].ToObjectString();
ddlCountry_Update(strCountryCd); //Update Country & State DDL because Country can be a foreign country
ddlCountry.SelectedValue = strCountryCd;
inputCity.Text = dt.Rows[0]["City"].ToObjectString();
ddlState.SelectedValue = dt.Rows[0]["StateProvinceId"].ToObjectString();
inputZipcode.Text = dt.Rows[0]["Zipcode"].ToObjectString();
ddlCardType.SelectedValue = dt.Rows[0]["CardType"].ToObjectString();
}
}
When I load the page in the browser the <%# Eval("btnMode") %> does not get resolved to a value. I see this when I open the inspector:
<input
id="btnEdit"
class="<%# Eval("btnMode") %>"
type="submit"
name="ctl00$ctl00$ContentPlaceHolderFront$ContentPlaceHolderFront$rptList$ctl01$btnPrimary"
value=""
onclick="javascript:WebForm_DoPostBackWithOptions(new WebForm_PostBackOptions("ctl00$ctl00$ContentPlaceHolderFront$ContentPlaceHolderFront$rptList$ctl01$btnPrimary", "", true, "", "", false, false))" >
It is important to point out that this attribute CommandArgument='<%# Eval("PaymentSourceId") %>' does work, and btnMode does contain valid data.
As I wrote in a comment, not all properties in Asp.Net controls can be databound. CssClass is one that cannot be databound.
To get around this, you can add an OnItemDataBound event handler to the repeater where the Button is. In the event handler you can then user the e.Item.DataItem to get the value you want and set it as the CssClass on the button. Sample code:
<asp:Repeater ID="RepeaterTest" runat="server" OnItemDataBound="RepeaterTest_ItemDataBound">
<ItemTemplate>
<div>
<asp:Button ID="TestButton" runat="server" Text='<%# Eval("someText") %>'/>
</div>
</ItemTemplate>
</asp:Repeater>
and code behind:
protected void Page_Load(object sender, EventArgs e)
{
var testData = Enumerable.Range(1, 10).Select(i => new { someText = "Button " + i.ToString() }).ToList();
RepeaterTest.DataSource = testData;
RepeaterTest.DataBind();
}
protected void RepeaterTest_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
dynamic foo = e.Item.DataItem;
((Button)e.Item.FindControl("TestButton")).CssClass = foo.someText;
}
I want to bind a Hidden Field because I want to pass a value from code behind to the asp:Parameter Name="HOME_TEAM_COACH_ID" Type="Int32".
My asp:
<asp:FormView ID="FormView1" runat="server" OnItemUpdated="FormView1_ItemUpdating" >
<EditItemTemplate>
HOME_TEAM:
<asp:DropDownList ID="DropDownListHometeam" runat="server"
DataSourceID="SqlDataGetTeams"
DataTextField="NAME" DataValueField="ID" SelectedValue='<%# Bind("HOME_TEAM_ID") %>'>
</asp:DropDownList>
<asp:HiddenField runat="server" ID="testLabel" Value='<%# Bind("HOME_TEAM_COACH_ID") %>' />
</EditItemTemplate>
And c# behind is:
protected void FormView1_ItemUpdating(object sender, FormViewUpdatedEventArgs e)
{
if (FormView1.CurrentMode == FormViewMode.Edit)
{
DropDownList HomeTeamId = FormView1.FindControl("DropDownListHometeam") as DropDownList;
string team = string.Format("{0}", HomeTeamId.Text);
SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["BasketballConnectionString1"].ToString());
conn.Open();
string queryHome = "SELECT dbo.COACH.ID, dbo.COACH.SURENAME FROM dbo.COACH INNER JOIN dbo.GAMES ON dbo.COACH.TEAM_ID = dbo.GAMES.HOME_TEAM_ID WHERE (dbo.GAMES.HOME_TEAM_ID =" + team + ")";
SqlCommand cmd = new SqlCommand(queryHome, conn);
var Home_Coach_Id = cmd.ExecuteScalar().ToString();
HiddenField HomeCoachIdLabel = FormView1.FindControl("testLabel") as HiddenField;
HomeCoachIdLabel.Value = Convert.ToString(Home_Coach_Id);
conn.Close();
I want Help with the last four lines where I want to pass the Home_Coach_Id value to bind the asp:HiddenField ID="testLabel" Value='<%# Bind("HOME_TEAM_COACH_ID") %>'.
When I click update, it doesn't change the value in database. (When I debug, in the last lines it gives me the correct HomeCoachIdLabel.Value.)
any suggestions?
You do not need the explicitly set the HiddenField's Value property, because it is done by the <%# Bind("HOME_TEAM_COACH_ID") %> in your markup.
I believe your problem is that you are not returning the HOME_TEAM_COACH_ID from your query to the database in your SELECT statement:
SELECT dbo.COACH.ID, dbo.COACH.SURENAME FROM dbo.COACH
INNER JOIN dbo.GAMES ON dbo.COACH.TEAM_ID = dbo.GAMES.HOME_TEAM_ID
WHERE (dbo.GAMES.HOME_TEAM_ID =" + team + ")
The problem is that it needs the method prerender and not the method onitemupdated.
asp:FormView ID="FormView1" runat="server" OnPreRender="FormView1_OnPreRender" >
and also in c#
protected void FormView1_OnPreRender(object sender, FormViewUpdatedEventArgs e)
{
It also works when I put it in page load{ }.
The next step is to make the insert event....
I have a repeater for different updates identified by "Update_ID". Each "Update_ID" has a number of images associated to it.
Therefore, I decided to nest a repeater for the images inside the repeater for updates.
The problem is that the image repeater never shows up, even if there is data to show.
Here is the code in ASP.NET:
<asp:Repeater ID="RepeaterUpdates" runat="server" onitemcommand="RepeaterUpdates_ItemCommand">
<ItemTemplate>
<div style="border: thin solid #808080">
<table id="TableUpdates_Repeater" runat="server" style="width:100%; margin:auto; background-image:url(Resources/Icons/white-background.gif)">
<tr>
<td style="width:25%">
<br />
<asp:Label ID="LabelUpdateID_Repeater" runat="server" Text="Update ID" Enabled="false"></asp:Label>
<asp:TextBox ID="TextBoxUpdateID_Repeater" runat="server" Width="50px" Text='<%# Eval("Update_ID") %>' Enabled="false"></asp:TextBox>
</td>
</tr>
</table>
<asp:Repeater ID="RepeaterImages" runat="server">
<ItemTemplate>
<label>Hello</label>
<asp:TextBox Text='<%# DataBinder.Eval(Container.DataItem,"Image_ID") %>' runat="server"></asp:TextBox>
</ItemTemplate>
</asp:Repeater>
</div>
</ItemTemplate>
</asp:Repeater>
Here is the code-behind:
protected void RepeaterUpdates_ItemCommand(object source, RepeaterCommandEventArgs e)
{
SqlConnection conn5 = new SqlConnection(connString);
SqlDataReader rdr5;
RepeaterItem item = e.Item;
TextBox Update_ID = (TextBox)item.FindControl("TextBoxUpdateID_Repeater");
try
{
conn5.Open();
SqlCommand cmd5 = new SqlCommand("SelectImages", conn5);
cmd5.CommandType = CommandType.StoredProcedure;
cmd5.Parameters.Add(new SqlParameter("#update_id", Update_ID.Text));
rdr5 = cmd5.ExecuteReader();
if ((item.ItemType == ListItemType.Item) || (item.ItemType == ListItemType.AlternatingItem))
{
Repeater ImageRepeater = (Repeater)item.FindControl("RepeaterImages");
ImageRepeater.DataSource = rdr5;
ImageRepeater.DataBind();
}
}
finally
{
conn5.Close();
}
}
As previously stated, the child repeater never shows up, even if there is data to display. How can I solve this problem please? Thanks
Rather than onitemcommand, call OnItemDataBound
Change RepeaterCommandEventArgs to RepeaterItemEventArgs
In addition to #Curt. Below is the code.
Code Behind
class Images
{
public int Image_ID;
}
protected void RepeaterUpdates_ItemCommand(object source, RepeaterCommandEventArgs e)
{
RepeaterItem item = e.Item;
TextBox Update_ID = (TextBox)item.FindControl("TextBoxUpdateID_Repeater");
try
{
conn5.Open();
using (SqlCommand cmd5 = new SqlCommand("SelectImages", conn5))
{
cmd5.CommandType = CommandType.StoredProcedure;
cmd5.Parameters.Add(new SqlParameter("#update_id", Update_ID.Text));
List<Images> Lst = new List<Images>();
using (SqlDataReader rdr5 = cmd5.ExecuteReader())
{
while (rdr5.Read())
{
Lst.Add(new Images { Image_ID = Convert.ToInt16(rdr5["Image_ID"]) });
}
if ((item.ItemType == ListItemType.Item) || (item.ItemType == ListItemType.AlternatingItem))
{
Repeater ImageRepeater = (Repeater)item.FindControl("RepeaterImages");
ImageRepeater.DataSource = Lst;
ImageRepeater.DataBind();
}
}
}
}
finally
{
conn5.Close();
}
}
HTML
You should Register ItemBoundData Event
<asp:Repeater ID="rp" runat="server" onitemdatabound="rp_ItemDataBound">
<ItemTemplate></ItemTemplate>
</asp:Repeater>
protected void rp_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
}
I am rather new at asp.net.
I´m trying to use ImageButton to link to another page. ImageButton is inside a Repeater and the code is following:
<ul id = "ulMap">
<asp:Repeater ID="Repeater1" runat="server" >
<ItemTemplate>
<li>
<asp:ImageButton ID="ImageButton1"
CommandArgument='<%#Eval("Nav_ID") %>'
runat="server"
ImageUrl="~/Icons/Ny_mappa.png"
onclick="ImageButton1_Click" />
<br />
<asp:LinkButton ID="lnkButton"
CommandArgument='<%#Eval("Nav_ID") %>'
runat="server"
onclick="LinkButton3_Click"
Text='<%#Eval("Nav_Name") %>'></asp:LinkButton>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
And the code behind is the following:
protected void LinkButton3_Click(object sender, EventArgs e)
{
Guid guid = new Guid(((LinkButton)sender).CommandArgument);
var query = from n in dc.Nemanet_Navigations
where n.UserId == userGuid && n.Nav_pID == guid
orderby n.Nav_Name ascending
select n;
Repeater1.DataSource = query;
Repeater1.DataBind();
}
protected void ImageButton1_Click(object sender, ImageClickEventArgs e)
{
Guid guid = new Guid(((ImageButton)sender).CommandArgument);
var query = from n in dc.Nemanet_Navigations
where n.UserId == userGuid && n.Nav_pID == guid
orderby n.Nav_Name ascending
select n;
Repeater1.DataSource = query;
Repeater1.DataBind();
}
Well, for the LinkButton this works fine but not for ImageButton. Protected void ImageButton1_Click never happens. Can anybody help?
I thin you need to handle the Repeater_ItemCommand event to get this working properly. It'll probably save a bit of code as well.
MSDN Repeater ItemCommand
Also, if you're linking to another page do you need to postback to the page then perform some kind of redirection or would it make more sense to have that logic in the new page?
Instead of OnClick, you should you should OnCommand. Like this.
<ul id = "ulMap">
<asp:Repeater ID="Repeater1" runat="server" >
<ItemTemplate>
<li>
<asp:ImageButton ID="ImageButton1"
CommandArgument='<%#Eval("Nav_ID") %>'
runat="server"
ImageUrl="~/Icons/Ny_mappa.png"
OnCommand="ImageButton1_Click" />
<br />
<asp:LinkButton ID="lnkButton"
CommandArgument='<%#Eval("Nav_ID") %>'
runat="server"
OnCommand="LinkButton3_Click"
Text='<%#Eval("Nav_Name") %>'></asp:LinkButton>
</li>
</ItemTemplate>
</asp:Repeater>
</ul>
And this (notice the CommandEventArgs instead of EventArgs and ImageClickEventArgs):
protected void LinkButton3_Click(object sender, CommandEventArgs e)
{
Guid guid = new Guid(e.CommandArgument);
var query = from n in dc.Nemanet_Navigations
where n.UserId == userGuid && n.Nav_pID == guid
orderby n.Nav_Name ascending
select n;
Repeater1.DataSource = query;
Repeater1.DataBind();
}
protected void ImageButton1_Click(object sender, CommandEventArgs e)
{
Guid guid = new Guid(e.CommandArgument);
var query = from n in dc.Nemanet_Navigations
where n.UserId == userGuid && n.Nav_pID == guid
orderby n.Nav_Name ascending
select n;
Repeater1.DataSource = query;
Repeater1.DataBind();
}
You can't handle server-side events for repeater child controls like this.
Think of it this way - if there is 100 buttons, you need 100 event handlers for each button. ImageButton1_Click will only work for the ImageButton with the id of 1.
The answer is to wire up the ItemCommand event for your repeater.
Like this:
<asp:repeater id = "Repeater`" runat = "server" onItemCommand = "SomeEvent">
Then you handle the "SomeEvent" for all buttons that trigger this event:
protected void SomeEvent ( Object src, RepeaterCommandEventArgs e ) {
var whoClickedMe = ((ImageButton) e.CommandSource );
}
Here's a good article on doing this.