I want to create a "Are you sure?" system when user clicks the close button of window. Is it possible to catch FormClosing event in Unity ?
Thanks.
Edit:
void OnApplicationQuit()
{
DialogResult result = MessageBox.Show(
"Are you sure you want to cancel ?",
"Question",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
Application.Quit();
}
}
I tried this to open a dialog when user clicks (X) button. It works but, looks like it creates a new dialog each frame.
This question needs an updated answer as Application.CancelQuit() is deprecated and MonoBehaviour.OnApplicationQuit() doesn't prevent the application from closing.
To accomplish this exit confirmation method, it's better to use: Application.wantsToQuit.
From the docs:
Unity raises this event when the player application wants to quit.
Add an event handler to this event to receive a notification that application is attempting to quit.
When this event is raised the quit process has started but can be cancelled. This means the player is not guaranteed to quit. For a guaranteed quit event take a look at Application.quitting.
Return true and the quit process will continue. Return false and the quit process will cancel.
Example:
// When the application starts, append a method
// that will run when the user attempts to exit
[RuntimeInitializeOnLoadMethod]
static void RunOnStart() {
Application.wantsToQuit += WantsToQuit;
}
public static bool quitConfirmation = false;
static bool WantsToQuit() {
if(quitConfirmation) {
return true;
} else {
RequestQuitConfirmation();
}
return false;
}
static void RequestQuitConfirmation() {
DialogResult result = MessageBox.Show(
"Are you sure you want to cancel ?",
"Question",
MessageBoxButtons.YesNo,
MessageBoxIcon.Question);
if (result == DialogResult.Yes)
{
quitConfirmation = true;
Application.Quit();
}
}
Note: The return value of this event (Application.wantsToQuit) is ignored when exiting play mode in the editor. IMPORTANT: The return has no effect on iPhone. Application can not prevent termination under iPhone OS.
Have a look at MonoBehaviour.OnApplicationQuit() and Application.CancelQuit()
Related
When I start my application I need to check if one of my service is running. If service is not running then I have to allow the user to start the service and then execution continues. If User chooses not to start the service then I have to Exit the Application. For every 10 sec I have to pop up the message to start the service,during this time program execution should not continue.Below is the code I have written. The service which I am looking to be running has a event handler which notifies when service is available(event handler is WindowsServiceAvailableEventHandler).
I have two questions here
How to resume or interrupt the Thread which is sleeping(Thread.Sleep(10000);) as soon as ServiceAvailable Event is raised?
When user want to start the service then he will click on Yes button and Dailog Box Closes and user will not know if something is happening..so I am looking for something like progress bar which will tell user that it is waiting for the user to start the service...as soon as service is started progress bar should close.How to achieve this?
My code:
this.windowsService.ServiceAvailable += this.WindowsServiceAvailableEventHandler
While (!CheckifServiceStarted())
{
DialogResult dlgResult = MessageBox.Show("Service is not Started.Please start Service to continue", "Start Service", MessageBoxButtons.YesNo);
if (dlgResult == DialogResult.Yes)
{
Thread.Sleep(10000);
}
else
{
System.Environment.Exit(0);
}
}
private void DataServicesAvailableEventHandler(object sender, EventArgs e)
{
//How to Resume or Interrupt the Thread here?
}
You could replace your Thread.Sleep with ManualResetEvent.WaitOne to signal the change in the handler like so:
private ManualResetEvent serviceAvailableEvent = new ManualResetEvent(false);
this.windowsService.ServiceAvailable += this.WindowsServiceAvailableEventHandler
While (!CheckifServiceStarted())
{
DialogResult dlgResult = MessageBox.Show("Service is not Started.Please start Service to continue", "Start Service", MessageBoxButtons.YesNo);
if (dlgResult == DialogResult.Yes)
serviceAvailableEvent.WaitOne(10000);
else
System.Environment.Exit(0);
}
private void DataServicesAvailableEventHandler(object sender, EventArgs e)
{
serviceAvailableEvent.Set();
}
As for the progress bar, check this question out for example.
I am using CefSharp 37 in winforms. I have implemented IRequestHandler and want to write some ResourceHandler code in method OnBeforeResourceLoad.
in OnBeforeResourceLoad() I check some condition and on that basis I display a MessageBox with OK and Cancel buttons. By pressing Cancel I want to return true otherwise false. Code as below:
public bool OnBeforeResourceLoad(IWebBrowser browser, IRequest request, IResponse response)
{
if (!request.Url.Contains(ContentHelper.requestTrapKey)
{
var handler = browser.ResourceHandler;
if (handler != null)
{
handler.RegisterHandler(request.Url, ResourceHandler.FromStream(File.OpenRead(ContentHelper.contentRootPath), Path.GetExtension(ContentHelper.contentRootPath + final));
}
}
else if (!request.Url.Contains(ContentHelper.requestTrapKey + "course") && request.Url.Contains(ContentHelper.requestTrapKey))
{
if (MessageBox.Show("message", "title", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Cancel)
{
return true;
}
}
return false;
}
It is observed that sometime MessageBox() goes behind to main form and user waits for messagebox to come and also next code also in wait state to execute. I know that as MessageBox.Show() is called on other thread than main thread so that's why it's going behind.
So is there any way where I can show MessageBox or a message to user without going it behind and take input from user and accordingly return true or false to load resource.
Update
I tried as #Adil said in answer to wrap the code by MethodInvoker then MessageBox remain on top of form but as when I press any button on message box application get hanged.
I have written an parametrized constructor of MyRequestHandler class as :
public MyRequestHandler(MainForm mainform)
{
this.mainform = mainform;
}
Then as said by #Adil :
bool returnValue = false;
mainform.Invoke((MethodInvoker)(() =>
{
if (MessageBox.Show(mainform,"message", "title", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Cancel)
{
returnValue = true;
}
}));
return returnValue;
I tied with checking InvokeRequired of mainform but still it's
throwing same exception.
You not only need to check the InvokeRequired but you need to invoke on GUI thread. You can do that by using MethodInvoker.
If you have return with MethodInvoker delegate it will return from delegate instead of the method having MethodInvoker. You can set value of some bool variable to true, which you can use after delegate finishes its execution to return from the method.
bool returnValue = false;
mainform.Invoke((MethodInvoker)(() =>
{
if (MessageBox.Show(mainform,"message", "title", MessageBoxButtons.OKCancel, MessageBoxIcon.Question, MessageBoxDefaultButton.Button1) == DialogResult.Cancel)
{
returnValue = true;
}
}));
return returnValue;
I am alerting the user about the process complete like :
var result = MessageBox.Show("Completed!!", "Upload Status", MessageBoxButton.OK, MessageBoxImage.Information);
if (result == MessageBoxResult.OK)
{
result = MessageBox.Show("Do you want to Quit the application ?", "Quit Application", MessageBoxButton.YesNo, MessageBoxImage.Question);
if (result == MessageBoxResult.Yes)
{
OpenWebSite();
// I want to close the message box and complete application.
}
}
If I write this.Close..It is giving exception, So I wrote it like this :
Dispatcher.BeginInvoke(new Action(() => { this.Close(); }));
Still the page is only closing after two click on [Yes] button, which is making the the OpenWebSite(); to be called two times. ...
Any idea on what is causing this?
Use Application.Current.Shutdown()
protected override void OnBeforeInstall(IDictionary savedState)
{
base.OnBeforeInstall(savedState);
DialogResult result = DialogResult.None;
if (isExcelIsRunning())
{
result = MessageBox.Show("Excel is still running. Please save your work and close Excel, and then click \"Retry\" button to continue with installation.", "", MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning);
}
while (result == DialogResult.Retry)
{
if (!isExcelIsRunning())
{
break;
}
}
}
//check if excel is currently running
private bool isExcelIsRunning()
{
bool flag = false;
Process[] xlProc = Process.GetProcessesByName("excel");
if (xlProc != null)
flag = true;
return flag;
}
The above is the code I am about to use for my Installer Class.
What I want to achieve here is that I need the installer to check whether or not Excel is currently running during the installation. And if it is running, then there should be a pop-up message at the start of installation to alert user to close off Excel and the installer should pause until there's no Excel instance found in the process list any more.
Back to the code, I don't think that while block is quite right, as it could cause an endless loop after user clicks "Retry" button if in the mean time Excel is still running.
So what'd be the better approach? Would anyone here take a look at the above code and see where I can improve?
I think your code would be something like this:
while(isExcelRunning())
{
var result = MessageBox.Show("Excel is still running. Please save your work and close Excel, and then click \"Retry\" button to continue with installation.", "", MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning);
if (result != DialogResult.Retry)
{
//Handle Cancel
break;
}
}
This will keep displaying the alert in a loop, either until Excel exits, or they press cancel, at which you can do whatever you need to do; then we exit the loop (or you could return entirely out of the method).
The key here is display the alert repetitively, either until Excel is gone or they choose to cancel. If you need to do some code after the loop based on the response; perhaps something like this:
var userHasCancelled = false;
while(!userHasCancelled && isExcelRunning())
{
var result = MessageBox.Show("Excel is still running. Please save your work and close Excel, and then click \"Retry\" button to continue with installation.", "", MessageBoxButtons.RetryCancel, MessageBoxIcon.Warning);
if (result != DialogResult.Retry)
{
userHasCancelled = true;
}
}
if (userHasCancelled)
{
//User cancelled...
}
else
{
//Continue.
}
WPF
I need CLEAN and START again the window SetPathCharger.xaml when the user clic on "Yes" the message box, the problem is the application send a error InvalidOperationException.
public void ExitProgram(string message)
{
var restart = MessageBox.Show("Do you want do it again?",
"Question", MessageBoxButton.YesNo,
MessageBoxImage.Question).ToString();
if (restart == "Yes")
{
_setPathCharger.ShowDialog();
}
if (restart == "No")
{
Environment.Exit(0);
}
}
How can I do this?
You should just create and show a new SetPathCharger window, instead of reusing the current one. Something like:
_setPathCharger = new SetPathCharger();
_setPathCharger.ShowDialog();
Assuming ExitProgram is in some outer scope and is triggered after closing _setPathCharger then I suppose you are trying to ShowDialog() a disposed object.
Try to:
_setPathCharger = new SetPathCharger();
_setPathCharger.ShowDialog();