I am developing a asp.net application using C#.
I created an .aspx page and placed four buttons on different locations on the page.
On server side, I want to use just one click event for all four buttons.
Here is my code:
aspx page
<asp:Button ID="Button1" runat="server" CommandArgument="Button1" onClick = "allbuttons_Click" />
<asp:Button ID="Button2" runat="server" CommandArgument="Button2" onClick = "allbuttons_Click" />
<asp:Button ID="Button3" runat="server" CommandArgument="Button3" onClick = "allbuttons_Click" />
<asp:Button ID="Button4" runat="server" CommandArgument="Button4" onClick = "allbuttons_Click" />
cs page
protected void allbuttons_Click(object sender, EventArgs e)
{
//Here i want to know which button is pressed
//e.CommandArgument gives an error
}
#Tejs is correct in his comment, looks like you want something like this:
protected void allbuttons_Click(object sender, EventArgs e)
{
var argument = ((Button)sender).CommandArgument;
}
Use
OnCommand =
and
protected void allbuttons_Click(object sender, CommandEventArgs e) { }
Actually you don't need to pass the CommandArgument at all to know which button you pressed. You can get the ID of the button like below:
string id = ((Button)sender).ID;
You can assign command-text to your buttons as follows:
protected void allbuttons_Click(Object sender, CommandEventArgs e) {
switch(e.CommandName) {
case "Button1":
Message.Text = "You clicked the First button";
break;
case "Button2":
Message.Text = "You clicked the Second button";
break;
case "Button3":
Message.Text = "You clicked Third button";
break;
case "Button4":
Message.Text ="You clicked Fourth button";
break;
}
}
Related
I have got 10 button/Links in aspx page. I need to maintain a session variable on only ONE button click and for all other 9 click/action I need to change the value in session variable.
How can I get this in a best way, instead of writing in those 9 click actions.
Please suggest
You can re-use the same event for multiple buttons, and check the 'sender' to see which button was clicked.
Markup:
<asp:Button ID="Button1" runat="server" OnClick="GenericButtonClick" Text="Button" />
<asp:Button ID="Button2" runat="server" OnClick="GenericButtonClick" Text="Button" />
CS:
protected void GenericButtonClick(object sender, EventArgs e)
{
Button button = sender as Button;
switch(button.ID)
{
case "Button1":
//Maintain Session Variable
break;
default:
//Change Value in Session Variable
break;
}
}
You then set all your buttons to use the same event handler
I use mostly the command event handler instead of click, so in aspx side, you would have something like this:
<asp:Button ID="Button1" runat="server" OnCommand="DoSomething" CommandName="SetSession" CommandArgument="true" />
<asp:Button ID="Button2" runat="server" OnCommand="DoSomething" CommandName="SetSession" CommandArgument="false" />
<asp:Button ID="Button3" runat="server" OnCommand="DoSomething" CommandName="SetSession" CommandArgument="false" />
And in the back end cs file, there would be only one event handler like this:
protected void DoSomething(object sender, CommandEventArgs e)
{
if (e.CommandArgument.ToString() == "true")
{
// set session
}
}
The benefit of using CommandEventHandler is that even later on you change the button to ImageButton or LinkButton, you don't need to change the event signature, it works for all.
You can make a property in which you can set the session value and you can also get value from this property. I have made it private because it is used only in that page where you need.
private static string SetGetSession
{
set { HttpContext.Current.Session["Mairaj"] = value; }
get { return HttpContext.Current.Session["Mairaj"].ToString(); }
}
Here is how you can use it
protected void btnOne_Click(object sender, EventArgs e)
{
SetGetSession = "Mairaj";
}
protected void btnTwo_Click(object sender, EventArgs e)
{
SetGetSession = "Ahmad";
}
protected void btnTh_Click(object sender, EventArgs e)
{
SetGetSession = "Minhas";
}
If you want it to be used in other pages as well you can make a class and make this property public you will be able to access it everywhere.
I have a textbox and submit button created using the design mode.
When the submit button is pressed, it will retrieve the user input from the textbox and then make a query to my database.
It will then display a list of dynamic buttons according to the information retrieved from my database.
However, the event handler for the buttons does not fire when clicked. I guess my problem is the postback but I cannot create those buttons in page_load etc. because I need to get the user input (from the textbox when submit button is pressed) before i can load the buttons.
How can i solve this problem?
Thank you.
Edit (codes):
protected void subBtn_Click(object sender, EventArgs e)
{
//database setup codes
.......
while (reader.Read())
{
Button detailsBtn = new Button();
detailsBtn.Text = reader["fName"].ToString();
//doesn't fire
detailsBtn.Click += new EventHandler(detailsBtn_Click);
memPanel.Controls.Add(detailsBtn);
}
}
Main problem is Postback regenerate dynamic controls on each postback if those controls does not exists.
For quick demo see this code
ASPX CODE
<form id="form1" runat="server">
<asp:Button ID="Button1" runat="server" Text="Button" onclick="Button1_Click" />
<asp:Panel ID="pnl" runat="server"></asp:Panel>
</form>
ASPX.CS CODE
protected void Page_Load(object sender, EventArgs e)
{
if(IsPostBack)
{
generate();
}
}
public void generate()
{
if (!pnl.HasControls())
{
for (int i = 0; i < 4; i++)
{
Button detailsBtn = new Button();
detailsBtn.Text = "fName" + i.ToString();
detailsBtn.ID = i.ToString();
detailsBtn.Click += new EventHandler(detailsBtn_Click);
pnl.Controls.Add(detailsBtn);
}
}
}
protected void Button1_Click(object sender, EventArgs e)
{
generate();
}
protected void detailsBtn_Click(object sender, EventArgs e)
{
}
Sound to me like you could easily refactor your page to use a simple <asp:Repeater runat="server" ..></asp:Repeater> instead of dynamically adding controls to a Panel.
Here is a very simple complete sample:
RepeaterTest.aspx
<asp:Content ID="Content2" ContentPlaceHolderID="MainContent" runat="Server">
<asp:TextBox ID="theTextBox" runat="server"></asp:TextBox>
<asp:Button ID="theButton" runat="server" OnClick="theButton_Click" Text="Click me" />
<asp:Repeater ID="test" runat="server">
<ItemTemplate>
<asp:Button ID="theRepeaterButton" runat="server" Text='<%# Eval("fName") %>' OnClick="theRepeaterButton_Click" />
</ItemTemplate>
</asp:Repeater>
</asp:Content>
RepeaterTest.aspx.cs
public partial class RepeaterTest : System.Web.UI.Page
{
protected void Page_Load(object sender, EventArgs e)
{
}
protected void theButton_Click(object sender, EventArgs e)
{
string filter = theTextBox.Text;
// below row simulates fetching data using the filter text in the text box
var data = Enumerable.Range(0, 20).Select(i => new { fName = filter + " " + i });
test.DataSource = data;
test.DataBind();
}
protected void theRepeaterButton_Click(object sender, EventArgs e)
{
var button = (Button)sender;
// do something here based on text/commandname/commandargument etc of the button
}
}
I have an item template within repeater:
<ItemTemplate>
<li>
<input type="radio"
value="<%# GetAssetId((Guid) (Container.DataItem)) %>"
name="AssetId"
<%# SelectAsset((Guid) Container.DataItem) %> />
</li>
</ItemTemplate>
I have a method that compares ids and decides whether to check the radio button.
protected string SelectAsset(Guid uniqueId)
{
if (uniqueId == GetSomeId())
return "checked=\"checked\"";
return string.Empty;
}
SelectAsset gets hit, but it doesn't select a radio button on a post back, but it does work if I just refresh the page. What am I doing wrong here?
Answer here: How to display "selected radio button" after refresh? says that it's not possible to achieve, is this really the case?
Thank you
Update
It appears that view state isn't available for simple controls if they don't have a runat attribute. I have solved this by using a custom GroupRadioButton control. Thank you for your help.
I'd suggest using a RadioButtonList:
Page Code
<asp:RadioButtonList RepeatLayout="UnorderedList" OnSelectedIndexChanged="IndexChanged" AutoPostBack="true" ID="RadioRepeater" runat="server" />
<asp:Label ID="SelectedRadioLabel" runat="server" />
Code Behind
if (!Page.IsPostBack)
{
/* example adds items manually
- you could iterate your datasource here as well */
this.RadioRepeater.Items.Add(new ListItem("Foo"));
this.RadioRepeater.Items.Add(new ListItem("Bar"));
this.RadioRepeater.Items.Add(new ListItem("Baz"));
this.RadioRepeater.SelectedIndex = this.RadioRepeater.Items.IndexOf(new ListItem("Bar"));
this.RadioRepeater.DataBind();
}
protected void IndexChanged(object sender, EventArgs e)
{
this.SelectedRadioLabel.Text = string.Format("Selected Item Text: {0}", this.RadioRepeater.SelectedItem.Text);
}
I assume you only need to select one item.
As described in the comments, it even works to access the SelectedItem in the Page_Loadevent handler:
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
// previous code omitted
}
else
{
string foo = this.RadioRepeater.SelectedItem.Text;
}
}
If you are creating all your controls dynamically at run-time (directly from code), then things are a little different. Here is the code that I used:
Page Code
<form id="form1" runat="server">
</form>
Code Behind
protected void Page_Load(object sender, EventArgs e)
{
RadioButtonList rbl = new RadioButtonList();
rbl.AutoPostBack = true;
rbl.SelectedIndexChanged += rbl_SelectedIndexChanged;
rbl.Items.Add("All");
// generate your dynamic radio buttons here
for (int i = 0; i<5; i++)
{
rbl.Items.Add(string.Format("Dynamic{0}", i));
}
form1.Controls.Add(rbl);
if (!Page.IsPostBack)
{
rbl.SelectedValue = "All";
PopulateTextBox(rbl.SelectedValue);
}
}
void rbl_SelectedIndexChanged(object sender, EventArgs e)
{
RadioButtonList foo = (RadioButtonList)sender;
PopulateTextBox(foo.SelectedValue);
}
void PopulateTextBox(string selection)
{
TextBox box = new TextBox();
box.Text = selection;
form1.Controls.Add(box);
}
I have following simple controls on a page
WebForm1.aspx
<asp:Panel ID="Panel1" runat="server">
</asp:Panel>
<br />
<asp:Label ID="lblContent" runat="server" ></asp:Label>
Some code behind in WebForm1.aspx.cs :
protected void Page_Load(object sender, EventArgs e)
{
Button btn = new Button();
btn.ID = "btnTest";
btn.Text = "I was dynamically created";
btn.Click += new EventHandler(btnTest_Click);
Panel1.Controls.Add(btn);
}
void btnTest_Click(object sender, EventArgs e)
{
lblContent.Text = "btnTest_Click: " + DateTime.Now.ToString();
}
In short, when I dynamically create a Button (btnTest) in the Page_Load event and assign event handler btnTest_Click to the button. Click event then, when loading the page I see btnTest appearing and when clicking on it the event handler btnTest_Click is invoked. OK, No problem.
I have a problem though when I try following scenario... first, I add a button to the page in designer mode.
<asp:Panel ID="Panel1" runat="server">
</asp:Panel>
<asp:Button ID="btnCreateDynamically" runat="server"
Text="Create Button Dynamically"
onclick="btnCreateDynamically_Click" />
<br />
<asp:Label ID="lblContent" runat="server" ></asp:Label>
I move the code from Page_Load to the button event handler of btnCreateDynamically as follows
protected void btnCreateDynamically_Click(object sender, EventArgs e)
{
Button btn = new Button();
btn.ID = "btnTest";
btn.Text = "I was dynamically created";
btn.Click += new EventHandler(btnTest_Click);
Panel1.Controls.Add(btn);
}
When running the WebApp now and clicking on btnCreateDynamically, btnTest is created but when I click on btnTest its event handler is NOT invoked ???
Why not?
How can I make this work?
You should add the dynamic controls in the Page's Init event handler so that the ViewState and Events are triggered appropriately.
Try doing this:
protected void Page_Init(object sender, EventArgs e)
{
Button btn = new Button();
btn.ID = "btnTest";
btn.Text = "I was dynamically created";
btn.Click += new EventHandler(btnTest_Click);
Panel1.Controls.Add(btn);
}
You need to re-create dynamic control on each postback, see my previous answer to a similar question here
I am trying to set a ViewState-variable when a button is pressed, but it only works the second time I click the button. Here is the code-behind:
protected void Page_Load(object sender, EventArgs e)
{
if (Page.IsPostBack)
{
lblInfo.InnerText = String.Format("Hello {0} at {1}!", YourName, DateTime.Now.ToLongTimeString());
}
}
private string YourName
{
get { return (string)ViewState["YourName"]; }
set { ViewState["YourName"] = value; }
}
protected void btnSubmit_Click(object sender, EventArgs e)
{
YourName = txtName.Text;
}
Is there something I am missing? Here is the form-part of the design-file, very basic just as a POC:
<form id="form1" runat="server">
<div>
Enter your name: <asp:TextBox runat="server" ID="txtName"></asp:TextBox>
<asp:Button runat="server" ID="btnSubmit" Text="OK" onclick="btnSubmit_Click" />
<hr />
<label id="lblInfo" runat="server"></label>
</div>
</form>
PS: The sample is very simplified, "use txtName.Text instead of ViewState" is not the correct answer, I need the info to be in ViewState.
Page_Load fires before btnSubmit_Click.
If you want to do something after your postback events have fired use Page_PreRender.
//this will work because YourName has now been set by the click event
protected void Page_PreRender(object sender, EventArgs e)
{
if (Page.IsPostBack)
lblInfo.InnerText = String.Format("Hello {0} at {1}!", YourName, DateTime.Now.ToLongTimeString());
}
The basic order goes:
Page init fires (init cannot access ViewState)
ViewState is read
Page load fires
Any events fire
PreRender fires
Page renders