Assuming I have the following repeater.
<asp:Repeater ID="MyRepeater" runat="server" onitemdatabound="MyRepeater_ItemDataBound">
<FooterTemplate>
</table>
<asp:Button ID="btnPrevious" runat="server" Text="<" />
<asp:Label ID="lblCurrentPage" runat="server" Text="<%# PagingStatus() %>" />
<asp:Button ID="btnNext" runat="server" Text=">" />
</FooterTemplate>
</asp:Repeater>
How can I handle the click events from btnPrevious and btnNext?
I have tried the following:
protected void MyRepeater_ItemDataBound(object sender, RepeaterItemEventArgs e)
{
Button btnPrevious = (Button)e.Item.FindControl("btnPrevious");
Button btnNext = (Button)e.Item.FindControl("btnNext");
if (btnPrevious != null)
btnPrevious.Click += btnPrevious_Click;
if (btnNext != null)
btnNext.Click += btnNext_Click;
}
But this has failed (The event is never raised)..
You can use them in the same way you would use a normal button event handler eg:
Html:
<asp:Button ID="btnNext" runat="server" CommandArgument="<%=Id%>" onclick="Button_OnClick" Text=">" />
Code:
protected void Button_OnClick(object sender, EventArgs e)
{
Button button = sender as Button;
if(button != null)
{
string commandArg = button.CommandArgument;
//Do Work
}
}
The you can use the command argument to find out which button was clicked.
Hope this helps.
I would suggest using the ItemCommand event of the repeater. You still have to add the commands to your buttons though. Like this:
<asp:Button ID="btnPrevious" runat="server" Text="<" CommandName="Previous"/>
protected void MyRepeater_ItemCommand(object source, RepeaterCommandEventArgs e)
{
if(e.CommandName.ToLower().Equals("previous")) {
//go back
}
else
{
//go forward
}
}
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 need your help to this case i can't find any solution in the web
I have datalist that build like this :
<ItemTemplate>
<%# DataBinder.Eval(Container.DataItem, "Name") %>
<asp:Button ID="Button1" runat="server" Text="Button" />
<%# DataBinder.Eval(Container.DataItem, "Enabled") %>
<asp:Button ID="Button2" runat="server" Text="Button" />
<asp:ImageButton ID="ImageButton1" runat="server" />
</ItemTemplate>
I want to enable the button just if the Enabled value that i get from the DB is equal to 1 , i have try to make this code below but didn't success.
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
int EnableDisable = Convert.ToInt32(((DataRowView)e.Item.DataItem).Row.ItemArray[1]);
if (EnableDisable != 1)
{
Button BT = e.Item.FindControl("ImageButton1") as Button;
BT.Enabled = true;
}}
any idea, can you help me ?
Thank you so much.
I don't see in your code where you disable the button when necessary. Have you tried this:
protected void DataList1_ItemDataBound(object sender, DataListItemEventArgs e)
{
int EnableDisable = Convert.ToInt32(((DataRowView)e.Item.DataItem).Row.ItemArray[1]);
ImageButton BT = e.Item.FindControl("ImageButton1") as ImageButton;
BT.Enabled = (EnableDisable == 1);
}
change this line
Button BT = e.Item.FindControl("ImageButton1") as Button;
by
ImageButton BT = e.Item.FindControl("ImageButton1") as ImageButton;
It kind of seems to me that there is an inherent difficulty in dynamically adding controls in ASP.NET Web Forms. Specifically, for a dynamically added control to be included in the ViewState, and have it's events properly wired up and so forth it is suggested that these be added during the Page_PreInit event.
That said, many times we'll probably want to add such controls according to an event, such as a user clicking a button. Control specific events like Click events always run after Init, and even after Load. Supposed the following .aspx....
<form id="form1" runat="server">
<div>
<asp:PlaceHolder ID="phAddresses" runat="server"></asp:PlaceHolder>
<br /><br />
<asp:Button ID="btnAddAddress" runat="server" Text="Add Another Address" OnClick="btnAddAddress_Click" />
...and the following .aspx.cs....
private static List<AddressUserControl> addresses = new List<AddressUserControl>();
protected void Page_PreInit(object sender, EventArgs e)
{
foreach (AddressUserControl aCntrl in addresses)
{
phAddresses.Controls.Add(aCntrl);
// Helper to find button within user control
addressButtonControl = findAddressControlRemoveButton(aCntrl);
addressUserControlButton.ID = "btnRemoveAddress" + addressCount;
addressUserControlButton.Click += new EventHandler(addressUserControlButton_Click);
addressCount++;
}
}
protected void btnAddAddress_Click(object sender, EventArgs e)
{
AddressUserControl aCntrl = LoadControl("~/UserControls/AddressUserControl.ascx") as AddressUserControl;
addresses.Add(aCntrl);
}
Now in the above situation the number of User Controls displayed is always one behind the number the user has actually added, because the Click event doesn't run until after PreInit, where controls must be added to the placeholder. I must be missing something here, because this seems inherent to the ASP lifecycle, and to require some 'hack' or other.
EDIT - Yeah for some reason EventHandlers I add during btnAddress_Click() won't run, only EventHandlers I add during Page_Init, or declaratively in markup. This is what I tried to do...
protected void btnAddAddress_Click(object sender, EventArgs e)
{
AddressUserControl aCntrl = LoadControl("~/UserControls/AddressUserControl.ascx") as AddressUserControl;
addresses.Add(aCntrl);
phAddresses.Controls.Add(aCntrl);
findAddressControlRemoveButton(aCntrl);
addressUserControlButton.ID = "btnRemoveAddress" + addresses.Count;
///////////////////////////////////////////////////////////////////////////////////
// ADDED EVENT HANDLER HERE
//////////////////////////////////////////////////////////////////////////////////////
addressUserControlButton.Click += new E ventHandler(addressUserControlButton_Click);
}
...but the event won't fire as I've said. Any ideas?
EDIT - Here's the markup for my AddressUserControl. There's no logic in the code behind file
<%# Control Language="C#" ClassName="AddressUserControl" AutoEventWireup="true" CodeBehind="AddressUserControl.ascx.cs" Inherits="XFAWithUserControl.UserControls.AddressUserControl" %>
<asp:Panel ID="pnlAddressForm" runat="server">
<asp:Label ID="lblStreet" runat="server" Text="Street Address"></asp:Label>
<asp:TextBox ID="txtStreet" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblCity" runat="server" Text="City"></asp:Label>
<asp:TextBox ID="txtCity" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblState" runat="server" Text="State"></asp:Label>
<asp:TextBox ID="txtState" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblZip" runat="server" Text="Zip"></asp:Label>
<asp:TextBox ID="txtZip" runat="server"></asp:TextBox>
<br /><br />
<asp:Button ID="btnRemoveAddress" runat="server" Text="Remove Address" />
</asp:Panel>
right now my click event for btnRemoveAddress is just something silly like this...
private void addressUserControlButton_Click(object sender, EventArgs e)
{
Button thisButton = sender as Button;
thisButton.Text = "Why Hello";
}
but my goal is to have it remove the associated AddressUserControl, so that a user can add and/or remove an arbitrary number of AddressUserControls from the page by clicking buttons.
EDIT - Here's what I have now, still doesn't work
protected void btnAddAddress_Click(object sender, EventArgs e)
{
AddressUserControl aCntrl = LoadControl("~/UserControls/AddressUserControl.ascx") as AddressUserControl;
addresses.Add(aCntrl);
phAddresses.Controls.Add(aCntrl);
findAddressControlRemoveButton(aCntrl);
addressUserControlButton.ID = "btnRemoveAddress" + addresses.Count;
aCntrl.ChangeText += new EventHandler(addressUserControlButton_Click);
}
private void addressUserControlButton_Click(object sender, EventArgs e)
{
Button thisButton = sender as Button;
thisButton.Text = "Why Hello";
}
AddressUserControl.ascx
<asp:Panel ID="pnlAddressForm" runat="server">
<asp:Label ID="lblStreet" runat="server" Text="Street Address"></asp:Label>
<asp:TextBox ID="txtStreet" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblCity" runat="server" Text="City"></asp:Label>
<asp:TextBox ID="txtCity" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblState" runat="server" Text="State"></asp:Label>
<asp:TextBox ID="txtState" runat="server"></asp:TextBox>
<br /><br />
<asp:Label ID="lblZip" runat="server" Text="Zip"></asp:Label>
<asp:TextBox ID="txtZip" runat="server"></asp:TextBox>
<br /><br />
<asp:Button ID="btnRemoveAddress" runat="server" Text="Remove Address" OnClick="btnRemoveAddress_Click" />
</asp:Panel>
AddressUserControl.ascx.cs
public event EventHandler ChangeText;
protected void Page_Load(object sender, EventArgs e)
{
}
public void btnRemoveAddress_Click(object sender, EventArgs e)
{
if (this.ChangeText != null)
{
ChangeText(sender, e);
}
}
You need to have the logic in your click handler add to the panel's Controls collection as well as to the list of controls, like this:
protected void btnAddAddress_Click(object sender, EventArgs e)
{
AddressUserControl aCntrl = LoadControl("~/UserControls/AddressUserControl.ascx") as AddressUserControl;
addresses.Add(aCntrl);
phAddresses.Controls.Add(aCntrl);
}
UPDATE:
In your user control, you need to define an event that can be defined in the page that hosts the user control, like this:
AddressUserControl.cs (code-behind):
public event EventHandler RemoveAddress;
protected void removeAddressUserControlButton_Click(object sender, EventArgs e)
{
// Find out if the event has been set, if so then call it
if (this.RemoveAddress!= null)
{
RemoveAddress(sender, e);
}
}
Now on your page where you are using the user control, do this:
// Wire up the user control's event
nameOfUserControl.RemoveAddress += new EventHandler(addressUserControlButton_Click);
Finally, implement the addressUserControlButton_Click event:
protected void addressUserControlButton_Click(object sender, EventArgs e)
{
// Do your dynamic control creation here or whatever else you want on the page
}
I have 2 events that I want to fire from a user control back to it's parent.
"UserSelected" and "NoUsersSelected"
One fires when a user is selected and the other fires when all the users have been removed.
My problem is "UserSelected" works, but "NoUsersSelected" fails... In the code snippets below, I have commented the line that fails.
UPDATE:
When I comment all code relating to the first event handler, the 2nd one starts working.
Here is the code on my child (user) control:
public event EventHandler UserSelected;
public event EventHandler NoUsersSelected;
protected virtual void onUserSelected(System.EventArgs e)
{
if (UserSelected != null) UserSelected(this, e);
}
protected virtual void onNoUsersSelected(System.EventArgs e)
{
**###** PROBLEM ! - NoUsersSelected is always null so doesn't fire event **###**
if (NoUsersSelected != null) NoUsersSelected(this, e);
}
And to raise the events, I use buttons inside a GridView TemplateField:
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnSelect" CommandArgument='<%# Eval("UserID") %>' CommandName="SelectUser" ToolTip="Select User" runat="server" UseSubmitBehavior="false" CssClass="GridBtn_Select" CausesValidation="false" />
</ItemTemplate>
</asp:TemplateField>
<asp:TemplateField>
<ItemTemplate>
<asp:Button ID="btnDelete" CommandArgument='<%# Eval("UserID") %>' CommandName="DeleteUser" ToolTip="Delete User" runat="server" OnClientClick="javascript:if(!confirm('Are you sure?')) return false;" UseSubmitBehavior="false" CssClass="GridBtn_Delete" CausesValidation="false" />
</ItemTemplate>
</asp:TemplateField>
And here is the code behind for these buttons:
if (e.CommandName == "SelectUser")
{onUserSelected(System.EventArgs.Empty);}
and...
if (e.CommandName == "DeleteUser")
{ //this is where I remove the user from the grid...
if (gridUsers.Rows.Count < 1)
{onNoUsersSelected(System.EventArgs.Empty);}
.
On the parent page that hosts the user control:
protected void Page_Load(object sender, EventArgs e)
{
//Bind to the event on child control
GridAdvertiserUsers.UserSelected += UserSelected_EventHandler;
GridAdvertiserUsers.NoUsersSelected += NoUsersLinked_EventHandler;
}
and the functions that the events call:
void UserSelected_EventHandler(object sender, EventArgs e)
{ //do stuff here }
void NoUsersLinked_EventHandler(object sender, EventArgs e)
{ //Do other stuff }
UPDATE:
When onUserSelected is called, both Events seem to have their methods wired up correctly
But when onNoUserSelected is called, they are both null:
Ok, so I'm struggling with using asp:formview.
I've got the formview up and running and I've added the 'Edit' button.
<asp:FormView runat="server" id="fwHotelDetails" DataKeyNames="id" OnDataBound="fwHotelDetails_DataBound" OnModeChanging="fwHotelDetails_ModeChanging" >
<ItemTemplate>
// (..) some code here which outputs some data
<asp:Repeater runat="server" id="repScore">
<ItemTemplate>
<span class="item"> Some output here</span>
<asp:LinkButton ID="EditButton" runat="server" CausesValidation="False" CommandName="Edit" Text="Edit" />
</ItemTemplate>
</asp:Repeater>
<EditItemTemplate>
Test test, anything??
</EditItemTemplate>
</ItemTemplate>
</asp:FormView>
I've tried thefollowing solutions in the code behind - none of them works:
protected void fwHotelDetails_ItemCommand(object sender, FormViewModeEventArgs e)
{
if (e.CommandName.Equals("Edit"))
{
fwHotelDetails.ChangeMode(e.NewMode);
}
}
and this:
protected void fwHotelDetails_ModeChanging(object sender, System.Web.UI.WebControls.DetailsViewModeEventArgs e)
{
fwHotelDetails.ChangeMode((FormViewMode)e.NewMode);
}
Clicking the Edit button only gives me the following error message:
The FormView 'fwHotelDetails' fired event ModeChanging which wasn't handled
What more needs to be done?
This page is a great reference for FormView controller: http://authors.aspalliance.com/aspxtreme/sys/web/ui/webcontrols/FormViewClass.aspx
Update: I've updated code to refelct Phaedrus suggestion.
Current status is that even after clicking Edit button, the content from ItemTemplate is loaded.
You have to specify which method handles the ModeChanging event. This event is raised when a FormView control attempts to switch between edit, insert, and read-only mode, but before the mode actually changes.
<asp:FormView OnModeChanging="fwHotelDetails_ModeChanging" />
The second parameter of your method signature is 'DetailsViewModeEventArgs' it should be 'FormViewModeEventArgs'.
void fwHotelDetails_ModeChanging(Object sender, FormViewModeEventArgs e)
{
}
Just Simply write code in formview's Item_Command
protected void formview_ItemCommand(object sender, FormViewCommandEventArgs e)
{
if (e.CommandName == "Edit")
{
formview.DefaultMode = FormViewMode.Edit;
formview.DataBind();
}
if (e.CommandName == "Cancel")
{
formview.DefaultMode = FormViewMode.ReadOnly;
formview.DataBind();
}
}