I'm creating a link dynamically. The NavigateUrlproperty of the link is set on a call to a method. But I don't want to call the method before the link is clicked because there are so many of such links.
Any help on how to do it is appreciated. Thanks.
public void CreateLink()
{
LinkButton link = new LinkButton();
link.Click += new EventHandler(link_Click);
string key = GetKey();
}
private void link_Click(object sender, EventArgs e)
{
var url = GetLinkUrl(e.???);
Response.Redirect(url);
}
public string GetLinkUrl(string key)
{
//do things to retrieve url
return url;
}
Update: Many thanks, all :) I am going to use LinkButton, as seen in updated code above.
But I forgot to ask: There is a key associated with each link which is needed to get the URL. How can I
What you're doing is potentially quite complex; you would need to output back to the client something indicating a call to a code-behind method to be executed before the navigation occurs, for example:
HyperLink link = new HyperLink();
link.Attributes.Add("onclick", "doClientsideCode();");
...
Then, a bit of JavaScript:
function doClientsideCode() {
// Do a call to a service or similar, to run the method you're wanting to run.
// This will then do the navigation you require.
}
Thus, my suggestion would actually be a LinkButton; this will fire an event that you can capture server-side, via something similar to:
public void link_Click(object sender, EventArgs e) {
// Run my method
// Issue response.redirect to correct URL.
}
[Edit - in answer to the edited question, you have access to the properties CommandName and CommandArgument when using a LinkButton which should do what you require. However, I do feel that that part should now be a separate question.]
One alternative is to use an ASP button instead of Hyperlink, and bind the GetLinkUrl function inside a click handler for the button. Then run Response.Redirect('yourURL') to execute the link.
EDIT: As Adrian said above, a LinkButton will be the best of both worlds - it is styled like a Hyperlink, but you can set a click handler for it to get the URL dynamically, only when the button is actually clicked.
Related
I define a button like this:
Button info = new Button();
info.Command += Button_Command;
info.CommandName = "handleinfoclick";
info.CommandArgument = id;
And I tried to write a command handler here:
private void Button_Command(object sender, CommandEventArgs e)
{
Debug.WriteLine("HERE IN BUTTON COMMAND");
}
But the command handler is not being called. I have worked on this for a while and I haven't been able to find a solution. The button has to be defined in the codebehind because it is on a dynamic table and the function it calls will need the commandargument to interact with that row's data.
If it is web forms, then assigning server events dynamically will no work. I think the best approach is to assign events statically in your code and use some variables to define specific status. Then you can set the variables values and process them inside event and make decision to do some work.
I'm trying to decide using switch case which operation to take where ever section i choose to enter in the page, thus when posting back it will take the right action.
This is the button (Note, this is not the button i'm posting with, rather the one where i enter the section of editing credentials)
<input type="button" value="Edit credentials" onclick="ShowWindow('#EditDetails', 2500); <%WhatToDo = "ChangeUserInfo";%>" />
Code-behind:
public string WhatToDo = "";
protected void Page_Load(object sender, EventArgs e)
{
if (IsPostBack)
{
switch (WhatToDo)
{
case "ChangeUserInfo": ChangeUserInfo();
break;
}
}
}
protected void ChangeUserInfo(){ something }
The posting seems to work, other than the fact that it doesn't run the switch case...
don't know what to do and what am i doing wrong.. If anyone knows what am i doing wrong it'll be great :)
You hook up events in ASP.Net, ASP.Net hides the request and response object for you and wraps it into an Event Driven Architecture . So you don't need to handle the button being pressed in the Page_Load. Instead you need:
Server side button in the .aspx:
<asp:Button runat="server" ID="cmdResubmit" OnClick="cmdAddBooking_Click" Text="Resubmit" />
and an event with the same name as the OnClick in the code behind:
protected void cmdAddBooking_Click(object sender, object e)
{
//put code button code here
SomeClass.value = 123;
SomeClass.StringValue = "1234";
//etc. etc.
}
notice the name of the method matches: OnClick="cmdAddBooking_Click" in the button!
That's it. If you want multiple buttons then add multiple <asp:Button> with multiple event attached to them.
Note:
Clicking a button also triggers a page load (and your event) so any code in the Page_Load event will run on every button click. You can avoid this by wrapping it in if (IsPostBack), this means the code inside this if statement will only run on load not on postback
So I'm currently trying to add to each day of a .net calendar control one dynamic linkbutton (on the dayRender event). The problem I have is that the linkbutton href does not appear. It's not a problem of the linkbutton event not firing, the href= doesn't even appear, so it doesn't fire any postback. This means that the button looks like this in the html part:
<a class="delete79" ID="Delete_2014-09-01"> Delete </a>
My code looks like this:
protected void MyCalendar79_DayRender(object sender, DayRenderEventArgs e)
{
List<MenuDia> dayList = new List<MenuDia>();
foreach (var itemMenu in ListMenuDays)
{
if (itemMenu.Dia.CompareTo(e.Day.Date) == 0)
{
dayList.Add(itemMenu);
}
}
LinkButton deleteButton = new LinkButton();
deleteButton.CssClass = "delete79";
deleteButton.Text = "Delete";
deleteButton.ID = "Delete79_" + dayList[0].Dia.ToString("yyyy-MM-dd");
deleteButton.Click += delegate(object o, System.EventArgs a)
{
//simple stuff here, tried putting simple generic response.redirect
//and stuff like that but it wasn't the problem
};
}
I don't wanna sound rude but don't tell me that it's because I'm using a delegate instead of an eventhandler. First of all I tried changing that already (same thing happened) and second I usually do it like this when it's super simple so I don't have to create a separate method.
Also, I've tried changing the ID to something more predictable (Delete_+a simple index), that's not the problem unfortunately =(.
Any other ideas? Maybe it's because I'm doing it on dayrender and you can't do it there? How can I achieve the same thing then?
So yeah I found the problem. MSDN page says:
Because the DayRender event is raised while the Calendar control is
being rendered, you cannot add a control that can also raise an event,
such as LinkButton. You can only add static controls, such as
System.Web.UI.LiteralControl, Label, Image, and HyperLink.
That's the problem. I will do a hack manually that generates the same postback of a hidden linkbutton. Thanks everyone!
I searched the internet over and over, and this seems to be very straightforward, but somehow it's not working.
I'm trying to create a web forms application in C#.
Button1 is supposed to download a lot of data from a website, and I want to Label1 to display "downloading" while the code in Button1 runs, and "done" after the code finishes, but Label1 is not changing at all after button click.
code is below:
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "downloading";
//code for downloading data
Label1.Text = "done";
}
That's not going to work. That's all server-side code. The updated HTML is not sent back to the browser until after the Button1_Click handler is finished executing. So the browser will only see the "done" label text. Never the "downloading" text.
The easiest way to achieve your desired effect is to use client-side javascript (maybe using jquery) to update the label text to "downloading" before you submit the form. You can put your client-side javascript in the OnClientClick property of the asp.net button. The server-side code can then download the data and change the label text to done.
I don't know if this will still be helpful since the post is rather old, but I stumbled upon the question while searching for an answer to a question of my own.
Just use the Label1.Update() function after you change the label's text.
If you want to change text from downloading to done then you may do this:
Label lbl = (Label)this.FindControl("Label1");
if (lbl != null)
{
lbl.Text = "done";
}
protected void Button1_Click(object sender, EventArgs e)
{
Label1.Text = "downloading";
//code for downloading data
Label1.Text = "done";
Label1.Refresh;
}
I have a button that calls function A()
When I click on it I want the calls to be made in that order:
A()
Page_Load()
Right now it's doing:
Page_Load()
A()
Is there a way around that or is it just by design and there's nothing I can do about it?
The easiest way to do this would be to use a HTML Submit button and check to see if it is in the Form on every postback in Page_Init
public void Page_Init(object o, EventArgs e)
{
if(!string.IsNullOrEmpty(Request.Form["MyButtonName"]))
{
A();
}
}
And in your ASP.NET code:
<Button Type="Submit" Name="MyButtonName" Value="Press Here To Do Stuff Early!" />
I think that will work.
Control events (such as the click events of buttons) are called after page_load. The controls are not guarenteed to be fully initialized prior to page_load. If you really need to call a function before page_load has been called based on whether a button has been pressed you'll have to examine the request to check if the button has been pressed (basically old school ASP)
You need to call your function in the Page_Init. Page_Init will happen before Page_Load.
Here's an Overview of the ASP.NET Page Lifecycle.
Not exactly: ASP.NET will always call Page_Load before handling postback events like Button_Click.
However, you can accomplish what you want by redirecting to your page after handling the postback event. (Using the Post-Redirect-Get pattern.)
Inside your Page_Load method, you can avoid running any relevant code twice by checking to see if it's a postback first:
if (!this.IsPostBack) {
// Do something resource-intensive that you only want to do on GETs
}
As Jeff Sternal answered, The Post-Redirect-Get pattern is a good way of solving a problem like this.
In my circumstances i had a calendar and if you clicked a date it would add that to a scheduler. The scheduler would have buttons on each new date that needed to have onclick functions tied to them.
Because the new row was being added with a linkbutton(on the calendar), in the code the new scheduler date was being added at the Postback event handling meaning that the new set of buttons wouldn't have a command tied to them.
The page life Cycle
Post Get Redirect
I don't think it's possible, at least, not in the way described by your question. When you click a button it will send a request to the server which in turn will start processing it, and follow the ASP.NET Page Lifecycle as posted by Joseph.
Alternatively you could try making an AJAX call to a page without reloading the current one you're on and do whatever processing you require.
This is what you want to do for Page Init is called before Page Load.
Take a look at the ASP.net Page Life Cycle
public void Page_Init(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
//CALL YOU FUNCTION A()
}
}
protected void Page_Load(object sender, EventArgs e)
{
if (!Page.IsPostBack)
{
}
}
If your actual goal here is to have your "page loading code" happen after your event handler runs -- for example, if clicking your button changes something in your database, and you want the updated data to be reflected on the page when it loads -- then you could have your "page loading code" get called from a method that gets called later in the ASP.NET page life cycle than your event handler, such as Page_PreRender, instead of calling it from Page_Load.
For example, here's a simplified excerpt from an .aspx.cs page class that has a button event handler that runs before the page population logic, and a confirmation message that is visible on the page only after the button was clicked:
// Runs *before* the button event handler
protected void Page_Load() {
_myConfirmationMessage.Visible = false;
}
// Runs *after* the button event handler
protected void Page_PreRender() {
// (...Code to populate page controls with database data goes here...)
}
// Event handler for an asp:Button on the page
protected void myButton_Click(object sender, EventArgs e) {
// (...Code to update database data goes here...)
_myConfirmationMessage.Visible = true;
}