I'm trying to develop a simple app for Windows Phone 8, and there are many requirements for the use of the Back Button. As I don't want the Back Button to simply GoBack in back stack, I'd like to pop up a message box to warn the user that this action will bring him back to main menu.
Problem is, this page has to be reloaded some times, and the following code stop working properly after 1 reload. The messagebox opens multiple times. And the more times I reload, the more MessageBox appears.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using Microsoft.Phone.Controls;
using Microsoft.Phone.Shell;
using BackButtonTests.Resources;
namespace BackButtonTests
{
public partial class MainPage : PhoneApplicationPage
{
public MainPage()
{
InitializeComponent();
}
protected override void OnNavigatedTo(System.Windows.Navigation.NavigationEventArgs e)
{
base.OnNavigatedTo(e);
NavigationService.Navigating += NavigationService_Navigating;
}
void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
{
if (e.NavigationMode == NavigationMode.Back)
{
e.Cancel = true;
MessageBox.Show("Quit");
}
}
private void Restart_Click(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/MainPage.xaml?reload=" + DateTime.Now.ToString(), UriKind.RelativeOrAbsolute));
//Use this fake reload query with unique value as a way to "deceive" the system, as windowsphone does not support NavigationService.Reload, and using simply the Uri of the same page will not properly load everything
}
private void Quit_Click(object sender, RoutedEventArgs e)
{
MessageBox.Show("Quit");
}
}
}
This is just a test code I wrote, that shows exactly the problem I'm experiencing in my actual project. Of course there are 2 buttons written in xaml.
And the code won't work until you first reload the page, as it's not NavigatedTo when it's the front page (not a problem in my actual project).
Any clues of what I'm doing wrong?
NOTE: I'm not interested in changing the event handler (to OnBackKeyPress, for instance). I'm interested in understanding what's going on with the handler I chose (NavigationService.Navigating, NavigationMode.Back). Thanks
Updated following additional information that clarifies the questing
Changing your navigating event handler to will mean the event isn't fired on every page in the stack
void NavigationService_Navigating(object sender, NavigatingCancelEventArgs e)
{
NavigationService.Navigating -= NavigationService_Navigating;
if (e.NavigationMode == NavigationMode.Back)
{
e.Cancel = true;
MessageBox.Show("Quit");
}
}
No longer neccessary
Override OnBackKeypress instead of navigating
protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
{
var DoYouWantToQuit = MessageBox.Show("Are you sure you want to Quit", "Quit", MessageBoxButtons.OkCancel);
if (DoYouWantToQuit != MessageBoxButton.Ok)
{
e.Cancel = true
}
base.OnBackKeyPress(e);
}
Related
This question already has answers here:
Process.Start to open an URL, getting an Exception?
(4 answers)
Closed 1 year ago.
I am very interested in C# winforms. I decided to make it open a browser window once I click on a link label with the default browser. I searched on the internet and found the following code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace GUI
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
}
private void panel1_Paint(object sender, PaintEventArgs e)
{
}
private void linkLabel1_LinkClicked(object sender, System.Windows.Forms.LinkLabelLinkClickedEventArgs e)
{
try
{
VisitLink();
}
catch (Exception ex)
{
MessageBox.Show("Unable to open link that was clicked.");
}
}
private void VisitLink()
{
// Change the color of the link text by setting LinkVisited
// to true.
linkLabel1.LinkVisited = true;
//Call the Process.Start method to open the default browser
//with a URL:
System.Diagnostics.Process.Start("http://www.microsoft.com");
}
}
}
When I tried it in my code, I clicked on the link but nothing shows up. Not even an exception pops up, which made me confused. Can anyone help me? Thanks!
The link is correctly marked as visited after the click ? If not, the event is probably not even got fired. Check if you correctly add the callback on the click event
i have been tasked to make a layout of 4 web browsers, that later could be used for security cameras.
the web browser part was easy, but i have been stuck at making it responsive, because when you run it and maximize the program, the resolution of the web browsers stay the same. and since this program will be running on a big flat screen it has to respond to the resolution.
i have looked all over the internet and have not found a solution. i have tried the anchoring but when i do this and i enlarge the program the browsers start over lapping each other. i have tried putting them in a flow grid and a table grid. other things i found was "this.AutoSize = true;" but i am kinda new to c# forms and do not understand this.
can anyone help?
the code and a few photo's of what happens
how it is now
what happens when enlarged
the code:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace webspace
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
private void Form1_Load(object sender, EventArgs e)
{
webBrowser1.Navigate("www.nos.nl");
webBrowser2.Navigate("www.google.com");
webBrowser3.Navigate("www.facebook.com");
webBrowser4.Navigate("www.google.com/maps");
this.AutoSize = true;
}
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
this.Text = e.Url.ToString() + "is loading...";
}
private void webBrowser2_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
this.Text = e.Url.ToString() + "is loading...";
}
private void webBrowser3_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
this.Text = e.Url.ToString() + "is loading...";
}
private void webBrowser4_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
this.Text = e.Url.ToString() + "is loading...";
}
private void webBrowser2_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
private void webBrowser3_DocumentCompleted_1(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
}
}
Have a layout that is two Orientation=Horizontal SplitContainers, inside another SplitContainer that is Orientation=Vertical (or vice versa, two verticals one on either side of a horizontal)
When the form resizes, set all the SplitContainer's SplitterDistances to 50% of the width/height as appropriate.. Unless the user's customised them (in which case decide what to do, like have a proportional resize, thereby allowing the user to have some views bigger than others)
Make the web browser controls Dock=Fill their panels
Note that the WebBrowser control is quite old now, and should probably be replaced with a WebView2 (Chrome-based Edge)
Is this possible to detect a mouse click (Left/Right) anywhere (Inside and Outside the Form) in an if statement? And if it's possible, how?
if(MouseButtons.LeftButton == MouseButtonState.Pressed){
...
}
Here is a starter, if I understood your needs of "clicking from outside the window" and Hans Passant's suggestion doesn't fit your needs. You might need to add an event handler for Form1_Click.
CAUTION: This code is provided to illustrate the concept. The threading synchronization in this sample is not 100% correct. Check the history of this answer for an attempt at a more "threading correct" one that sometimes throws exceptions. As an alternative, to get rid of all threading issues, you could have the task in StartWaitingForClickFromOutside be instead always running (aka be always in "listen" mode) as opposed to trying to detect the "within the form" or "outside the form" states and starting/stopping the loop accordingly.
using System;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;
namespace WindowsFormsApp1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.MouseLeave += Form1_MouseLeave;
this.Leave += Form1_Leave;
this.Deactivate += Form1_Deactivate;
this.MouseEnter += Form1_MouseEnter;
this.Activated += Form1_Activated;
this.Enter += Form1_Enter;
this.VisibleChanged += Form1_VisibleChanged;
}
private AutoResetEvent are = new AutoResetEvent(false);
// You could create just one handler, but this is to show what you need to link to
private void Form1_MouseLeave(object sender, EventArgs e) => StartWaitingForClickFromOutside();
private void Form1_Leave(object sender, EventArgs e) => StartWaitingForClickFromOutside();
private void Form1_Deactivate(object sender, EventArgs e) => StartWaitingForClickFromOutside();
private void StartWaitingForClickFromOutside()
{
are.Reset();
var ctx = new SynchronizationContext();
var task = Task.Run(() =>
{
while (true)
{
if (are.WaitOne(1)) break;
if (MouseButtons == MouseButtons.Left)
{
ctx.Send(CLickFromOutside, null);
// You might need to put in a delay here and not break depending on what you want to accomplish
break;
}
}
});
}
private void CLickFromOutside(object state) => MessageBox.Show("Clicked from outside of the window");
private void Form1_MouseEnter(object sender, EventArgs e) => are.Set();
private void Form1_Activated(object sender, EventArgs e) => are.Set();
private void Form1_Enter(object sender, EventArgs e) => are.Set();
private void Form1_VisibleChanged(object sender, EventArgs e)
{
if (Visible) are.Set();
else StartWaitingForClickFromOutside();
}
}
}
If I understood you incorrectly, you might find this useful: Pass click event of child control to the parent control
When user clicks outside the form control, it losses the focus and you can make use of that.which means you have to use the _Deactivate(object sender, EventArgs e) event of the form control to make this work. Since which will trigger when the form loses focus and is no longer the active form. Let Form1 be the form, then the event will be like the following:
private void Form1_Deactivate(object sender, EventArgs e)
{
// Your code here to handle this event
}
One method is to cover the entire screen with a borderless form with the properties set to transparent (a few percent above completely transparent, not sure if total transparency works but you won't notice the difference) and also set to topmost. Then use the events from the form. As soon as a click is detected this will not affect anything underneath the form (which in my application is something I want to happen) but the form could be closed and another mouse click simulated a fraction of a second later to activate the controls that are underneath. I had no problem using the windows API to use mouse hooks in VB6 but cannot seem to find something that works in c# with the 2019 version of .NET so this is a good workaround. Of course to be really clever you could use an irregular forms method to make the transparent form the same shape as the mouse and follow it.
Note: I have just found the complete code to do it using hooks that mere mortals can get up and running at once! KeyboardMouseHooks C# Library - CodePlex Archive
PS if you use my (dumb) method remember to create an escape key or button or you will have to restart your computer unless the form is programmed to disappear for real clicks as suggested!
I know this is late but maybe it helps someone. Using the MouseEventArgs of the MouseUp event of any control you can check for mouse button and wheel among other things. Here is an example.
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
this.MouseUp += Form1_MouseUp;
}
private void Form1_MouseUp(object sender, MouseEventArgs e)
{
if(e.Button == MouseButtons.Left)
{
DoSomething_LeftClick();
}
else if(e.Button == MouseButtons.Right)
{
DoSomething_RightClick();
}
}
private void DoSomething_LeftClick()
{
//Here some code
}
private void DoSomething_RightClick()
{
//Here some code
}
}
I'm using visual studio c# 2010 for the web browser.
WebBrowser 1 navigates to this link:
http://www.costco.com/IOGEAR-Wireless-1080p-HDMI-Transmitter-and-Receiver-3D-Compatible-2x-HDMI-Ports.product.100011675.html
When it reaches the page, it loads and freezes.
I don't think there is something wrong with the web page because chrome, firefox, and the regular IE9 don't freeze at all.
Only the web browser in my c# program freezes when it navigates to this link.
How do I prevent this from freezing? The web page seems to be calling some html data from another site.
I tried adding this code to my program
this.webBrowser1.ScriptErrorsSuppressed = true;
and I also changed the registry values of the web browser so that it will use internet explorer version 9 and so far these two did not work.
this is the code i'm using
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
webBrowser1.ScriptErrorsSuppressed = true;
}
private void button1_Click(object sender, EventArgs e)
{
webBrowser1.Navigate("http://www.costco.com/IOGEAR-Wireless-1080p-HDMI-Transmitter-and-Receiver-3D-Compatible-2x-HDMI-Ports.product.100011675.html");
}
private void webBrowser1_DocumentCompleted(object sender, WebBrowserDocumentCompletedEventArgs e)
{
}
}
}
The issue is not with the WebBrowser control per se, it is with how that particular website is trying to execute some Javascript that gets stuck in a loop.
Compare and contrast:
1) Change the url to http://google.com. Works fine.
2) Now. Add an event handler for the Navigating event. Something like:
this.webBrowser1.Navigating += new System.Windows.Forms.WebBrowserNavigatingEventHandler(this.webBrowser1_Navigating);
and
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
Console.WriteLine("Navigating to: " + e.Url);
}
You will see that there is a JavaScript function that is constantly trying to redirect the page. Here's what shows up in my console output (goes on indefinitely):
Navigating to: javascript:void((function(){document.open();document.domain='costco.com';document.write('<!DOCTYPE html>');document.close();})())
Navigating to: about:blank
Navigating to: javascript:void((function(){document.open();document.domain='costco.com';document.write('<!DOCTYPE html>');document.close();})())
Navigating to: about:blank
Navigating to: javascript:void((function(){document.open();document.domain='costco.com';document.write('<!DOCTYPE html>');document.close();})())
Navigating to: about:blank
Navigating to: javascript:void((function(){document.open();document.domain='costco.com';document.write('<!DOCTYPE html>');document.close();})())
Which makes the webBrowser control essentially unusable.
EDIT:
Ok, one stab at a workaround (this is probably terrible, but it's frustrating that the weird redirect loop is only happening in the WebBrowser control's browser).
If you block the Navigating event from being called before another Navigating event has completed, it loads the page and does not freeze, and the links appear to work. It goes something like this:
private void webBrowser1_Navigated(object sender, WebBrowserNavigatedEventArgs e)
{
Console.WriteLine("Navigated to: " + e.Url);
isNavigating = false;
webBrowser1.AllowNavigation = true;
}
bool isNavigating = false;
private void webBrowser1_Navigating(object sender, WebBrowserNavigatingEventArgs e)
{
if (isNavigating && e.Url.ToString().Contains("javascript:void((function(){document.open();document.domain='costco.com'"))
{
webBrowser1.Stop();
webBrowser1.AllowNavigation = false;
return;
}
isNavigating = true;
Console.WriteLine("Navigating to: " + e.Url);
}
I need to cancel the device back button event. I have tried the solution posted in Control press "back button" and disable close the application using a dialog for confirm - wp7, but it is not working for me. Am I doing something wrong? The application always exits whether ok or cancel is selected from the dialog box.
Here is my code...
using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using Microsoft.Phone.Controls;
using System.IO;
using System.Windows.Media.Imaging;
using System.Windows.Resources;
namespace GodTools
{
public partial class MainPage : PhoneApplicationPage
{
// Constructor
public MainPage()
{
InitializeComponent();
this.CordovaView.Loaded += CordovaView_Loaded;
BackKeyPress += OnBackKeyPressed;
}
private void CordovaView_Loaded(object sender, RoutedEventArgs e)
{
this.CordovaView.Loaded -= CordovaView_Loaded;
// first time load will have an animation
Storyboard _storyBoard = new Storyboard();
DoubleAnimation animation = new DoubleAnimation()
{
From = 0,
Duration = TimeSpan.FromSeconds(0.6),
To = 90
};
Storyboard.SetTarget(animation, SplashProjector);
Storyboard.SetTargetProperty(animation, new PropertyPath("RotationY"));
_storyBoard.Children.Add(animation);
_storyBoard.Begin();
_storyBoard.Completed += Splash_Completed;
}
void Splash_Completed(object sender, EventArgs e)
{
(sender as Storyboard).Completed -= Splash_Completed;
LayoutRoot.Children.Remove(SplashImage);
}
void OnBackKeyPressed(object sender, System.ComponentModel.CancelEventArgs e)
{
var result = MessageBox.Show("Do you want to exit?", "Attention!",
MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
// Do not cancel navigation
return;
}
e.Cancel = true;
}
}
}
see also, same problem from the Cordova side
"backbutton" event won't fire
For your information: If you write an application (not an XNA game) you shoul avoid canceling back button. Otherwise your app will be canceled on passing Marketplace sertification.
Also you can override OnBackKeyPress method with the same code;
protected override void OnBackKeyPress(CancelEventArgs e)
{
var result = MessageBox.Show("Do you want to exit?", "Attention!",
MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
base.OnBackKeyPress(e);
return;
}
e.Cancel = true;
}
update
I've just created a new 'Silverlight for windows phone" solution. Opened MainPage.xaml.cs file and added this code to it:
// Constructor
public MainPage()
{
InitializeComponent();
BackKeyPress += OnBackKeyPressed;
}
void OnBackKeyPressed(object sender, System.ComponentModel.CancelEventArgs e)
{
var result = MessageBox.Show("Do you want to exit?", "Attention!",
MessageBoxButton.OKCancel);
if (result == MessageBoxResult.OK)
{
// Do not cancel navigation
return;
}
e.Cancel = true;
}
so there is only one page in this project. And it works. The target platform is Windows Phone OS 7.1, I've checked it on Mango device and on the standard emulator. I think the problem is somewhere else. Maybe some code crashes you application while you are trying to cancel back event?
Please, try to check it on new simple project.