I have an aspx page which posts a form back to itself, processes the form in a .cs page (in the DLL, not code behind) and then the code takes one of many branches based on that outcome.
This is a rough outline of what happens:
protected void Page_Load(object sender, EventArgs e)
{
LoanApplication oLoanApplication = new LoanApplication();
string sStep = Request.Form["step"];
oLoanApplication.Process(Request.Form); //Sets the value of the object
}
Then, in the Process method that is in the DLL code, I want it to trigger an event at this point:
public void Process(NameValueCollection pFormData)
{
SendApplicationToWebService();
//Trigger event here on aspx page
}
Basically I am trying to pass a variable returned from the SendApplicationToWebService(); into Google Tag manager.
There are many different branches the code could take, and I do not think it is a good solution to do it at the end - it is best to do it at the point the variable is assigned its value - that way I know all code is passing through this point.
Some of the branches redirect to different pages, so I cannot do this after the process method is called on the Page_Load because the code may never be executed.
Any ideas?
Why don't you pass a callback function to oLoanApplication.Process ?
take a look on this sample
Related
From research, the answer to my question seems to be a resounding no.
From Rob de la Cruz's answer here and Jonathan Wood's answer here, it seems that the only way to do it is to use JavaScript. Sadly, I don't have the necessary skill level to implement their solutions and I'm not completely sure it will work for my situation anyway. See what you think:
What I have (using asp.net and C# in VS2019) is a treeview control which:
1.1 At the first level, displays the names of customers.
1.2 Expand a customer node and the next level displays a list of sales order numbers for that customer.
1.3 Expand a sales order node and the third and final level displays a list of the sale items belonging to that particular sales order.
Pretty standard stuff I should imagine. Now, also pretty standard is that, when a node is clicked a procedure will make visible a formview which displays information about that object. When a customer node is clicked it will display the customer formview. When a sales order node is clicked it will display a sales order formview. When a sale item node is clicked... you can probably guess what it displays then.
And this is where things start to go off the rails. When a node is clicked, it's Value property is stored in a variable called _id. This variable is then stored in ViewState. When the PostBack happens, the idea is that the Page_Load event will read the value of _id from ViewState, run the showFormViews() procedure and display the relevant formview. I have it laid out like this:
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["_id"] == null)
{
_id = "";
}
else
{
_id = Convert.ToString(ViewState["_id"]);
}
if (!IsPostBack)
{
fillTreeView;
tv.CollapseAll();
}
showFormViews();
}
and when a node is clicked:
protected void tv_SelectedNodeChanged(Object sender, EventArgs e)
{
// (a) PostBack occurs and Page_Load is run *before* _id is set and stored in ViewState
_id = tv.SelectedNode.Value;
ViewState.Add("_id", _id);
showFormViews();
// (b) would be great to be able to fire off a PostBack programmatically right here!
}
(the .aspx markup is just a TreeView and three FormViews linked to ObjectDataSources)
As I now know from this helpful page:
"The initialisation part of the page lifecycle will execute before the
event handler of the control that caused the post back. Therefore the
code in the page’s Init and Load event handler will execute before the
code in the event handler for the button that the user clicked."
As written at line (a) above, when the treeview node is clicked, the page is posted back and Page_Load is run whilst _id is still null. Because _id is null the showFormViews() procedure hides all of the formviews.
Then the SelectedNodeChanged event fires, _id is set and the showFormViews() procedure sets the relevant formview to visible. But of course, by now all of the controls have been rendered and so... nothing happens.
Being able to somehow fire a PostBack at line (b) would work out wonderfully. Page_Load would fire and run showFormViews() but this time with _id being what it should be.
Various variations at line (b) of:
Server.Transfer("samePage.aspx");
// or
Response.Redirect(Request.RawUrl, false);
don't work because they destroy ViewState (unless someone knows different?) so _id is back to being null again.
So if you can't fire off a PostBack in C# and if I can't work out how to implement the solutions by the two posters above (or even if they will be appropriate in this situation), is there any way I can restructure the page to make this - a fairly common pattern I would imagine - work (and please don't suggest MVC - I tried learning that and still have the nightmares!).
Many thanks in advance,
You can call in your PageLoad the method used to fill the ViewState... Like:
protected void Page_Load(object sender, EventArgs e)
{
if (ViewState["_id"] == null)
{
_id = "";
}
else
{
_id = Convert.ToString(ViewState["_id"]);
tv_SelectedNodeChanged(null, null);
}
if (!IsPostBack)
{
fillTreeView;
tv.CollapseAll();
}
}
Hi im hoping someone can assist im still new to programming and this is a noob question but i have created a Visual studio - C# (Windows Form Application) and now the question reads to Create a void method for each of my buttons i created in the form and telling me even what to name the method.
but on my research The void keyword is used in method signatures to declare a method that does not return a value.
LinkToAddresses () will be my void method for address the (button), so my question is do i just put in this void method and its going to do nothing?
im just going to link the full question maybe im just really not understanding this>?
''
The below form will represent the main form from which the user will navigate to the other forms. Meaning each button should be linked to the appropriate form. E.g. If button Manage Addresses is clicked the form managed addresses should be displayed. The Exit button should successfully terminate the program.
Create a void method for each button and name them as follow: LinkToAddresses (), LinkToCustomers (), LinkToDrivers (), LinkToStatus (), and LinkToFreight (). The methods should be called under the appropriate button. For the exit button create a void method named AppExit () this should terminate the program.
''
I would appreciate any help or guidance, thank you in advance.
Visual studio usually handles the button actions easily. Just place the buttons on your form, then rename the buttons to LinkToAddresses, LinkToCustomers, LinkToDrivers, LinkToStatus, LinkToFreight and AppExit. Then simply just double click on the each button and visual studio will create a void method for their click event.
using System;
using System.Windows.Forms;
namespace YourApp
{
public partial class FormMain : Form
{
private FormManagedAddresses formManagedAddresses = null;
public FormMain()
{
InitializeComponent();
}
private void LinkToAddresses_Click(object sender, EventArgs e)
{
if (formManagedAddresses != null)
{
formManagedAddresses.Close();
}
formManagedAddresses = new FormNews();
formManagedAddresses.Show();
}
private void AppExit_Click(object sender, EventArgs e)
{
Application.Exit();
}
}
}
The closest thing to a buttons function, is the Click Event Handler. While specific names vary based on Display technology (WinForms, WPF/UWP, ASP.Net), that is the general pattern for Graphical User Interfaces. It is called event driven programming. Even things that have a different programm flow like Games and Web Applications usually try to imitate it.
The signature of a event is given during its definition and must be strictly followed. Usually void NameOfTheEvent(object sender, SampleEventArgs e).
A return type of void is extremely common with events. If there is to be any output, that usually is handeled via a property in the Event Args or by directly doing stuff with the other GUI Elements.
If you want a button to do nothing, you just never give it a event handler. Every single button you ever used, was given a implicit or explicit event handler to do exactly what it did. If you want it to conditionally do nothing, either disable the Button so it can not be clicked, or put a proper if-statement into the event Handler.
A advanced topic would be the command pattern, where there is a bunch of commands in code behind. And each button, menu item and key combination is meerely a way to trigger said command - a representation for hte user to call the command.
You can share a single event across any number of Elements. AS you can see above, the pattern for events includes object sender as argument. This means you can check if it is a specific Button instance that called the event. Or even "unpack" the specific button, do look at stuff like Display String, Tag to get data from it. However, as a general rule retrieving data from the GUI is a bit frowned - ideally the GUI should only represent the data in the backend.
I am working on a Windows Phone application, here is the scenario that I have problem:
So I have three pages, lets call it page 1, 2, 3.
In page 1, I have a button called start downloading. Click the button and use NavigateService.Navigate(page2Uri) and navigate to page2.
Page 2 makes query and downloads images from internet, so in its OnNavigateTo handler, I check the page back stack, if it is navigated from page 1, I will do the download. In the app bar of this page, I have a button that can navigate to page3.
Page 3 is a list of options that will perform some behavior on the image that is downloaded in page2. Once I choose an option, I want to go back to page 2 and perform some behavior on the loaded image.Here the question comes: if I use NavigateService.Navigate(page2Uri) to navigate from page3 to page2, it will call the Page2 constructor and OnNavigateTo handler again, which will cause it to lose every instance variable it already got.
But if I use NavigatService.GoBack it will go back to page2, then realizes that the backstack top entry is page1 (since page1 -> page2 -> page3). So it will re-download everything again.
I dont want anything to be downloaded again when navigate back form page3 to page2. So wondering if anyone has good idea about this.
Thank you.
You can use the query parameters and NavigationEventArgs to help.
First, you can use the NavigationEventArgs to determine if the user is going forward or background by checking the NavigationMode.
Second, you can tell page 2 to download by using the query parameters.
From page1:
private void MoveToPage2FromPage1()
{
NavigationService.Navigate(new Uri("/Page2.xaml?shouldDownload=true", UriKind.Relative));
}
and page2:
protected override void OnNavigatedTo(NavigationEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back) return;
string shouldDownload = ""; //May not be needed if you'll only ever go to page 2 from page 1 to download...
if (NavigationContext.QueryString.TryGetValue("shouldDownload", out shouldDownload))
{
Convert.ToBoolean(shouldDownload);
}
}
There are several ways to pass data to another page:
You can use query parameters as Shawn suggested.
You can use global data stored somewhere like in app.cs
You can use a static class to hold the data.
You can use a shared viewModel to hold the parameters. (or static properties in the viewmodel)
It all depends on the particular case. I think Shawns suggestion of using query paramaters is probably the most 'correct' MVVM way, but the other methods have their place.
You need to implement the following function and the navigation service.
These code will definitely solve your problem
for two or more parameters, use this code
String download="true";
String file="image";
NavigationService.Navigate(new Uri("/Page3.xaml?download="+download+"&file="+file+"", UriKind.Relative));
OnNavigatedTo, add the following code on to your Page2
protected override void OnNavigatedTo(NavigationEventArgs e)
{
base.OnNavigatedTo(e);
String download=NavigationContext.QueryString["download"];
String file=NavigationContext.QueryString["file"];
}
For the above OnNavigatedTo function outputs true and image. You can use MessageBox.Show(); to output
I have a VERY large asp.net application, it has many different .cs files in the project. I would like to trigger one button handler's method from another project. The reason is that in the .cs file that the button handler is it, there are many variables and methods being used that are private and I dont want to change the accessibility of all of them to public in order to access them.
SIMPLY put. how can I call the method " protected void try_validate(object sender, EventArgs e)" from another method in a different .cs file?
I am trying to access resetPage from a different .cs file in the project. I HAVE placed the code for resetPage into a new method called WriteToDB but even that I cant call from the other .cs file
Is it possible if you place the logic within the handler into another public method and then you invoke it from where ever you need to?
Hy,
In my project asp.net (c#), I am using threading to process some messages. I have a display page that contain a listbox with all the actions that are taken in processing the message. And a class where I am processing the message.
Default.aspx:
protected void Page_Load(object sender, EventArgs e)
{
//starts the thread and call the method from Process.cs
}
public void SetListItem(string text)
{
myListBox.Items.Add(text);
myListBox.DataBind();
}
Process.cs
public class Process
{
public Process()
{
Default defaultPage;
defaultPage.SetListItem("==> Received message!");
}
}
But the listbox do not show nothing.
Does anyone has any ideea where I'm wrong?
Thanks.
Jeff
Remove the databind
myListBox.DataBind();
You don't need it since you are adding an item to the list collection. If you were setting the DataSource property, you would then have to use it. This is all depending on where in the life-cycle your update is firing as well. It could be that your update is being replaced by code somewhere else in the process as well.
In truth, I would take this out of being a separate thread. Since you need it to be updated before the page submits information to the browser, you either need to keep it in the same thread to make sure it completes, or you're going to need to have some sort of a check at the end of your page executing process to make sure it has finished. It is possible your thread is completing after the page has finished processing.
An asp.net page, such as Default generates html which is returned to the requesting browser. When this html has been generated and sent to the browser, there is no way you can add items on the server side to whatever is displayed in the browser.
So spawning threads that do some work is not necesarily a good idea for your current scenario.
Klaus is right. Once the page has been drawn it's just sitting there.
So, to do what you want to do, running Process in a seperate thread:
Write your output message in Process to a data store, even if that's just appending to a text file. Then, set your page to automatically refresh every X time, and refill your listbox on load with the content of that datastore.
Later on, when everything's working, you could use Ajax to make just the listbox refresh, instead of the whole page.