How to stop a event from firing + ASP.NET - c#

I have a WebPage on which I have to detect and prevent usage of Browser Refresh Button. (Now Please, dont suggest me Response.Redirect, I wont be able to use it in this scenario).
On looking at this page http://aspalliance.com/687_Preventing_Duplicate_Record_Insertion_on_Page_Refresh.4 I found the way. I'm planning to put this idea in a Control and place the control on every page.
Now that my page contains so many buttons and other controls. My concern is, If it is a refresh post... I dont want any events to get fired...
It will be tedious to go and check whether it is a refresh post in the beginning of every event as my entire application is almost built.
Any ideas that would help me.
Raja
Including the below text for sake of more clarity :
Hi All, I hope a little misunderstanding... I dont want to stop user pressing the Refresh button... But all I want is to adjust my application's response accordingly... Imagine a scenario, when user clicks BUTTON-A a popup window opens with another page. Now when the user comes back and clicks refresh button in the main window, the click event of BUTTON-A is fired again and popup window is opened again... In such scenario, I want to refresh the page as such, without opening the popup window. so, I need to stop ASP.NET from firing the click event of BUTTON-A (or any other similar buttons)

I know you're not going to want to hear this but users expect to be able to hit the refresh button. Breaking something they like will make them unhappy. They'll blame you and your name will be mud.
Just think about those sites that try to block the Back button: do you like them?

This is at least a starting point on how you can do it. I'm not sure all logic is 100%, but it is something to begin with...
protected void Page_Load(object sender, EventArgs e)
{
foreach (Control control in Controls)
{
DisableEvent(control);
}
}
protected void Page_PreRender(object sender, EventArgs e)
{
foreach (Control control in Controls)
{
UpdateViewstate(control);
}
}
private void DisableEvent(Control current)
{
foreach (Control control in current.Controls)
{
if (control.GetType() == typeof(Button))
{
if (IsPostBack)
{
if (Session["update" + control.ID].ToString() != ViewState["update" + control.ID].ToString())
{
RemoveClickEvent((Button)control);
}
else
{
((Button)control).Click += new EventHandler(Button_Disable);
}
}
else
{
Session["update" + control.ID] = Server.UrlEncode(System.DateTime.Now.ToString());
}
}
DisableEvent(control);
}
}
private void UpdateViewstate(Control current)
{
foreach (Control control in current.Controls)
{
if (control.GetType() == typeof(Button))
{
ViewState["update" + control.ID] = Session["update" + control.ID];
}
UpdateViewstate(control);
}
}
void RemoveClickEvent(Button b) {
System.Reflection.FieldInfo f1 = typeof(Button).GetField("EventClick", System.Reflection.BindingFlags.Static | System.Reflection.BindingFlags.NonPublic);
object obj = f1.GetValue(b);
System.Reflection.PropertyInfo pi = typeof(Button).GetProperty("Events", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
System.ComponentModel.EventHandlerList list = (System.ComponentModel.EventHandlerList)pi.GetValue(b, null);
list.RemoveHandler(obj, list[obj]);
}
protected void Button_Disable(object sender, EventArgs e)
{
Button b = (Button)sender;
Session["update" + b.ID] = Server.UrlEncode(System.DateTime.Now.ToString());
}

You cannot prevent the user from pressing the Refresh button. It's build in functionality in the browser that resends the previous request, get or post. It's just there.
That is why that you normally make a redirect after a post to a get (e.g. the user posts to user/1/edit and the response redirects to user/1/view), so that a refresh will not cause double post.
I'm sorry that this is not what you want to hear, but when making a web application, you should try to follow web standards and let the user be able to use those browser features that he/she expects: back, forward, and refresh. And I know that your application is almost finished.
But if you start creating hacks for preventing refresh, or other stuff where you're not flowing with the technology, but going up against the stream, your application will start carrying around a bad package, and as the application lives on and is extended, this bad package is going to be a burden for further development.

Related

Restarting/Resetting program when radiobutton is selected

I'm trying to figure out how I can reset my windows form application once the option to do so has been selected from a choice of to radio buttons. eg:.
So once "Yes" is selected the program resets. Here is what I have been trying.
private void EndOptions() {
if (anotheryes.Checked) {
RestartForm();
}
if (anotherno.Checked) {
//todo
}
}
The restartform method is just:
private void RestartForm() {
Application.Restart();
Application.ExitThread();
}
Right now, this only works if I press the "calculate ratio" button again. On click, the application will restart. I'm wanting it so that it resets just by clicking the Yes radiobutton.
The logic behind the button is as follows:
private void DisplayLogic() {
double height = 0, waist = 0;
if (WaistNumericCheck(out waist) && HeightNumericCheck(out height)) { //check if input is numeric, if true, move on to next check
if (CheckDimensionHeight(height) == true && CheckDimensionsWaist(waist) == true) { //check if dimensions are higher than the lower limits, if BOTH true, move on the next
ShowResult(height, waist); //shows results
DisableInputs(); //disables inputs while results are being shows
AnotherGroupBoxVisible();//makes the restart selection groupbox visible
EndOptions(); //check to see which option is selected
}
}
}
Any tips/help would be greatly appreciated thanks!
I have to say its an odd thing to have the entire app restart, just so the user could do another calculation.. The API you are using i.e. Application.Restart is documented for use with ClickOnce Applications
http://msdn.microsoft.com/en-us/library/system.windows.forms.application.restart(v=vs.110).aspx
I don't know if your app is click once or not.. but anyway, hoping you'd learn something new regardless, here is literal answer to your question..
http://msdn.microsoft.com/en-us/library/system.windows.forms.radiobutton.checkedchanged(v=vs.110).aspx
This event occurs when the value of the Checked property of a radio button changes.
Anyway, I do strongly recommend, that as suggested in comment above, you should reconsider how you want your app to provide a better user experience here..
If its just for learning, the event should help.. and feel free to explore other events on the control which might be of interest.
Handle the CheckedChanged event of the RadioButton, and then you can immediately restart as soon as it is clicked:
private void AnotherYes_CheckedChanged(object sender, EventArgs e)
{
if (AnotherYes.Checked)
{
Application.Restart();
}
}
http://msdn.microsoft.com/en-us/library/system.windows.forms.radiobutton.checkedchanged(v=vs.110).aspx

Implement a "click-here-to-expand" container

I have no better way of explaining it, but I want to implement a container that only is shown after the user clicked "Advanced" or a plus sign somewhere in the dialog. I have a login form and want to add some "Advanced" settings. But they should normally out of view.
Of course, the dialog has to resize nicely to hold the extended content.
How should I go to implement such a thing. I have tried some Google searches, but can't find the right search words. Windows doesn't seem to have it by default.
as John Willemse suggested, I ended up creating the functionality myself. I added a Panel in the form that I just set visible or invisible.
In the Form's constructor (to hide it on first view):
public FrmLogin() {
InitializeComponent();
pnlAdvanced.Visible = false;
Height -= pnlAdvanced.Height;
}
Then, I added a LinkLabel with this Clicked handler:
private void linkLabel1_LinkClicked(object sender,
LinkLabelLinkClickedEventArgs e) {
if (pnlAdvanced.Visible == false) {
Height += pnlAdvanced.Height;
pnlAdvanced.Visible = true;
} else {
Height -= pnlAdvanced.Height;
pnlAdvanced.Visible = false;
}
}
Works perfectly and no extra code needed.

Pause the processing of saving the data when modal popup show

How can I pause the processing of saving the data when modal popup showed?
and when I click the button inside that modal popup, the execution of saving the data will continue to process.
my Modal popup is acting like a message box...
here is my sample code:
bool overlap= false;
foreach (ListItem item in chkMBoxEmployeeList.Items)
{
if (overlap == true)
{
//Saving of data
}
else if (overlap == false)
{
ModalpopupExtender2.Show();
//In this condition, I will pause the execution of saving the data
}
}
//I used this after the ModalpopupExtender2.Show():
return;
//but I think, this will not be the answer, because my code will become very long if use that. I will rewrite again my code in the button in modalpopup if I use that.
Should I use Threading? is Threading working on ASP.Net?
Your save process is happening on the server but the modal dialog would be displayed on the client. You can't make the server wait for the user in the browser to respond. Instead the server processing has to end and send the modified page to the browser. Now the browser will again submit all the data together with the confirmation. Since you are using ASP.NET WebForms you get lucky since it handles the state automatically for such scenarios.
public void Save(bool confirmed)
{
if (!confirmed && NeedsConfirmation())
{
ShowModalWindow();
return;
}
// here perform the operation.
}
public void ButtonSave_Click(object sender, EventArgs e)
{
// this is the button that is normally displayed on the form
this.Save(false);
}
public void ButtonConfirm_Click(object sender, EventArgs e)
{
// this button is located within the modal dialog - so it is not shown before that.
this.Save(true);
}

WebBrowser control - wait for page loading after submit form

I am new to c# and its concepts, so i am sorry if this question is kind of dumb.
I try to do some automatation using the winforms webbrowser control
elements = webBrowser1.Document.GetElementsByTagName("input");
foreach (HtmlElement element in elements)
{
if (element.GetAttribute("value") == "Anzeigen")
element.InvokeMember("click");
}
while (webBrowser1.ReadyState != WebBrowserReadyState.Complete) Application.DoEvents();
// do some math on recived html
// ......
// show results
MessageBox.Show(numPlanets.ToString() );
So, to explain it:
Im looking for a Button with the value "Anzeigen", simulate a click on it, then wait till NEW page is loaded and do my calculations then.
Unfortunately my calculations are done on the OLD HTML content, because its not waiting for the page to load. Strangely if i enter an Thread.Sleep(5000); after the foreach loop, this Sleep is executed BEFORE the click is simulated, and the calculation fails also.
I just need some synchronous behavior for that click, withouth using an event.
Hope u can help me with that, sorry for my bad english
EDIT:
Solved it like this:
Variable bool webbbrowserfinished = false inside the class, if i want synchronous behavior, i do it like this:
webbrowserfinished = false;
// do navigation here
while (!webbrowserfinished)
{
Application.DoEvents();
Thread.Sleep(100);
}
webbrowserfinished = false;
You can try WebBrowser.DocumentCompleted Event
Occurs when the WebBrowser control finishes loading a document.
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("google.com");
webBrowser1.DocumentCompleted += new WebBrowserDocumentCompletedEventHandler(webBrowser1_DocumentCompleted);
}
void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
MessageBox.Show("Completed Now!");
}
Well it isn't the best of solutions but you could always start a timer when the web browser navigates, and set timer1.Tick to something like 3000, then within the timer1_Tick method you can do your calculations on the new page, and then timer1.Stop();.
There is probably a better solution using events but I'm not too good with web browsers myself.
You can use Thread.sleep(5000) to wait for your page to load, because if you don't, the navigate method will load a new doc into web browser control but it will not call document_complete_event_handler

How do I detect a change of tab page in TabControl prior to SelectedIndexChanged event?

I currently determine what page of a tabcontrol was clicked on via the SelectedIndexChanged event.
I would like to detect before the selected index actually changes, for validation purposes. For example, a user clicks a tab page other than the one they are viewing. A dialog is presented if form data is unsaved and asks if it's ok to proceed. If the user clicks no, the user should remain on the current tab.
Currently I have to remember the previous tab page and switch back to it after an answer of 'no.'
I considered MouseDown (and the assorted calculation logic), but I doubt that's the best way.
Add such an event to the tabControl when form_load:
tabControl1.Selecting += new TabControlCancelEventHandler(tabControl1_Selecting);
void tabControl1_Selecting(object sender, TabControlCancelEventArgs e)
{
TabPage current = (sender as TabControl).SelectedTab;
// Validate the current page. To cancel the select, use:
e.Cancel = true;
}
I've actually tried all of the events including the suggestions here and none of the mentioned events occur at the right time to actually trap moving from the tab.
Even the tab page validation event fires when entering the tab rather than leaving it - either that or there's something peculiar going on with my machine or .NET 4. On the other hand, in .NET 4 there is the Deselecting event which fires at the right time for my purposes.
private void tab_Deselecting(object sender, TabControlCancelEventArgs e)
{
}
The TabControl has a collection of TabPages, each of which you can enforce validation on, e.g.:
public partial class MyForm : Form
{
public MyForm()
{
InitializeComponent();
foreach (var page in _tabControl.TabPages.Cast<TabPage>())
{
page.CausesValidation = true;
page.Validating += new CancelEventHandler(OnTabPageValidating);
}
}
void OnTabPageValidating(object sender, CancelEventArgs e)
{
TabPage page = sender as TabPage;
if (page == null)
return;
if (/* some validation fails */)
e.Cancel = true;
}
}

Categories

Resources