I have a mainform where you can open another window and change options. One of the options is to copy highlighted text to the clipboard. if the user doesn't highlight text and clicks btnCopy then I want a message to be shown that no text was highlighted. When the user selects 'ok' I want the messagebox to close but I want the 'options' window to stay open.
Right now when the user clicks 'ok' both the message box and 'options' window closes. Why is the 'options' window closing?
Here is my code:
private void btnCopy_Click(object sender, EventArgs e)
{
string copySearch = txtSavedSearches.SelectedText;
if (copySearch == "")
{
DialogResult dialog = MessageBox.Show("You did not select anything to copy. Please select the query to copy.", "Copy search", MessageBoxButtons.OK, MessageBoxIcon.Information);
}
else
{
Clipboard.SetText(copySearch);
this.Close();
}
}
You obviously set the DialogResult property of btnCopy to something different than DialogResult.None.
If - in a Form that is not the application's main window - a Button is clicked that has the DialogResult property set (to something different than None), this click causes the Form to close and the calling ShowDialog() method to return that DialogResult.
Find out where you set that property and remove it.
From MSDN (Button.DialogResult):
If the DialogResult for this property is set to anything other than None, and if the parent form was displayed through the ShowDialog method, clicking the button closes the parent form without your having to hook up any events. The form's DialogResult property is then set to the DialogResult of the button when the button is clicked
Why is the 'options' window closing?
The following line will cause the options form to close:
this.Close();
You don't need to do anything to close a MessageBox; it goes away by itself when the user clicks OK, and then your code resumes running from the point where MessageBox.Show was called. MessageBox.Show is a method that returns a value denoting which button the user clicked to get the box to go away (the value varies depending on a) which buttons you chose to show as part of the call to .Show(...) and b) which button the user clicked
Right now when the user clicks 'ok' both the message box and 'options' window closes. Why is the 'options' window closing?
This cannot be, as the message box is shown in the do-if-true part of the IF, and the call to close the options form is called in the ELSE (do if false) part. These two parts cannot run in succession, they must be one or the other. Either your option form closes without a messagebox showing, or a messagebox shows and your form doesn't close
-
Edit:
Renee believes you have set this property:
on your btnCopy button to be something other than None
And then you have also opened your options form like this:
OptionsForm f = new OptionsForm();
f.ShowDialog();
These two things combined will conspire to cause your form options to close any time that btnCopy is clicked (unless the clickevent is canceled)
Related
I have a form that I open using ParentForm.ShowDialog().
Inside this form I call:
using (var form = new ChildForm())
{
var result = form.ShowDialog();
if (result == DialogResult.OK)
{
this.Cancelled = false;
}
}
I'm getting odd behavior when the child dialog is closed, the parent (calling) form also closes.
Why is this happening and how do I stop it?
I have a current solution that prevents the closing of the parent form by using the ParentForm_FormClosing event and a Boolean, but it feels like an over complicated solution
A form opened modally is closed when you set the property DialogResult to anything but DialogResult.None. The common practice to close a modal form is to set the DialogResult property of one or more buttons to some value of the same named enum. In that way, when the form engine sees a call to a click event handler checks the value of the DialogResult of the clicked button and, if nothing change that value, it closes the form when the click event handler ends returning that enum value to the caller.
So, you probably have copy/paste that button leaving the original DialogResult property unchanged and clicking that button will trigger the closure of the hosting form.
Of course before closing the hosting form, the engine will call the button click event in which you open a modal dialog and this suspends everything until you close the child form. At that point the code exits the click event and the form engine continue closing your parent form returning to the caller the value of the DialogResult property of the button.
If you don't want to automtically close the hosting form then you can set the form's DialogResult in code with
this.DialogResult = DialogResult.None;
or change the value of the button's DialogResult property
My intention is to make a pop up window (using another form) and show it when the delete file event is triggered. On this pop up form user should enter a correct password and then click OK button, this pop up disappears and the deletion operation proceeds. What I did is setting a string variable "Result" in the pop up form(form 2). When clicking the OK button, if the password entered is correct the "Result" is set for example "true". In my main form I made like:
if(form2.Result=="true"){ // deletion operation}
However this method doesn't work. When I entered the correct password and click OK in form2, nothing happens in my main form. Anybody got any idea how could I in main form detect the button click event in form2? Something like "if(form2.button.click==true)".
Thank you
You are not supposed to detect a button click on the second form, you should restructure your flow.
There are two common ways to do this. The easiest for you to implement would be instead of calling form2.Show() which you are probably doing right now, you should call form2.ShowDialog() which will halt the execution of the method in form1 until form2 is closed
So in form1 you'd have something like
private void DeleteSomething() {
if (form2.ShowDialog() == DialogResult.Ok) {
if (form2.result == true)
doDelete();
}
}
Note that checking for the DialogResult is a common practice, and unless you assign the property on Form2 specifying which button will act as the "Ok" button, you need to manually set the dialog result inside form2 like Sayse mentioned in his reply with
this.DialogResult = DialogResult.OK;
In your case, using the dialog result is not strictly necessary, but it's a common practice to implement support for different dialog results (ok, cancel, etc)
The whole other method is to not treat form2 as a dialog, but have form1 pass a reference to itslef to form2
then in form2 you can call a method on form1 to "authorize" the delete
so form1 would have one private method "confirmDelete" which would just show form2
and another public method "doDelete" which would be called by form2 when needed.
Unrelated note on your code:
If you are going to use a variable to indicate weather the authentication was succsefull, don't use a string with the value of "true", use a boolean.
If you wanted to return 3 or more states (eg, Result could be "Ok" "User Canceled" "Incorrect password" "Inssuficcient privileges", etc) then use an Enumeration.
ShowDialog() method returns a DialogResult which you can set to indicate how the form exited
using(var form2 = MyFormName())
{
if(form2.ShowDialog() == DialogResult.OK)
//success -- You can access form2 properties also.
}
Inside your button_ok event on the form, set the DialogResult to OK
this.DialogResult = DialogResult.OK;
I have an application (mainApp) that opens a modal dialog (collector) to ask for login details. The dialog has a cancel button and a standard close button in the top-right corner, and has FormBorderStyle = FixedDialog.
If I set collector.ShowInTaskBar = true I can right-click the dialog box in the taskbar and close it. The dialog disappears and the main app is still running. I can also right-click the whole group and choose 'Close all windows', which closes both the dialog and the application.
If I set collector.ShowInTaskBar = false I can right-click the application in the taskbar and click close, but nothing happens.
I would prefer not to show the dialog in the taskbar, but I would like the entire application to close when it is closed from the taskbar. How can I do this? If this is not possible I would settle for just closing the dialog.
Edit: the main form's FormClosing event does not get called when ShowInTaskBar = false
Does the MainForm's Closing event get fired when you click Close in the taskbar? If it does, and the app is being forced to stay open by the presence of the dialog windows, you could try programatically closing the dialog in the Closing event, and then letting the event run its course.
NOTE : This is all speculation, and it is a long time since I did any WinForms work so I may have the event names wrong.
When you close your forms that way, the message WM_SYSCOMMAND will be sent to your form window. We can catch this message with some informative params to perform according actions. Try this code:
public partial class Form1 : Form {
public Form1(){
InitializeComponent();
}
bool shownModal;//This flag will be used to determine if there is some
//modal dialog opening.
protected override void WndProc(ref Message m) {
if (m.Msg == 0x112)//WM_SYSCOMMAND
{
//SC_CLOSE = 0xf060
if (m.WParam.ToInt32() == 0xf060 &&
m.LParam.ToInt32() == 0 && shownModal)
{
//Your own code here
//You can close the main form or close the modal dialog
Close();
}
}
base.WndProc(ref m);
}
}
NOTE: You have to turn on the flag shownModal before showing your dialog and turn off after that. It's just a way to deal with it, you can try another way of your own.
You have to store reference to your login window in mainApp. Then you can write something like this:
loginWindow.Close();
which closes dialog window. This action can take place also inside loginwindow, for example user clicks button Close and window closes.
I have a form, wherein I prohibit the user from closing it when the user clicks the Close (X) button. Is it possible to show a tooltip on the Close (X) button whenever it is clicked? I want to do it to notify the user why the form would not close.
I thought of a messagebox but then I thought it would be too annoying to close the messagebox every time you click the Close (X) button.
Is there a better way to notify the user, than what I'm trying to do?
EDIT:
This is my code for the FormClosing event
private void InputForm_FormClosing(object sender, FormClosingEventArgs e)
{
if (e.CloseReason == CloseReason.UserClosing)
{
e.Cancel = true;
if (!mCloseReason)
{
e.Cancel = false;
}
}
}
I have a method that will save the inputs in the form. Once that method is finished, I need to automatically close the form. The if-statement will be true once I call this.Close(), this means I can't close the form. That's why I used a variable called mCloseReason to be able to close the form automatically. Now, that's why I was asking if I can notify the user through a tooltip once the Close (X) button is clicked.
I believe the default tooltip for the close(X) button is not editable without some hacking (and it is not practical).
Maybe what you could do is have a status field below your form, so when the user clicks the close button, it says in the status field "cannot close form (...)"
Or another idea is to have a message pop up somewhere on the form and go away after a little, indicating the form cannot be closed.
Another good idea was mentioned by Roger... just have a Close button somewhere on the form with a tooltip coded to it, and hide the forms' title bar?
I'm writing a Windows application that basically runs in the background with a notification icon to interact with it. The notification icon can do basic things like exit the application or show information about it. It can also launch a modal configuration dialog.
The code that creates the dialog is pretty straightforward:
using(var frmSettings = new SettingsForm(configuration))
{
frmSettings.ConfigurationChanged += ConfigurationChangedHandler;
frmSettings.UnhandledException += UnhandledExceptionHandler;
frmSettings.ShowDialog();
}
The SettingsForm class basically has three GroupBox controls, with a Label and TextBox control in each, and 4 Button controls at the bottom: "Advanced...", "Restore Defaults", "Cancel", and "Apply". Each TextBox has a Validating event handler wired up through the designer. Each button has a Click handler wired up through the designer. Each of them does pretty obvious things: opens another modal dialog with more advanced settings, restores the textboxes to their default values, closes the dialog, or saves the changes, fires the ConfigurationChanged event, and then closes the dialog (but only if all fields are valid!).
When there is a form entry error I cancel the corresponding Validating event by setting ((CancelEventArgs)e).Cancel = true. However, the default behavior of both forms was to prevent the user from changing focus when validation failed. I found this pretty annoying and eventually found the option in the designer to still automatically validate when the user leaves the field, but to allow them to leave even if validation fails: AutoValidate = EnableAllowFocusChange.[1]
My "Apply" button Click handler looks basically like this:
private void btnApply_Click(object sender, EventArgs e)
{
try
{
if(this.ValidateChildren())
{
this.Configuration.Field1 = this.txtField1.Text;
this.Configuration.Field2 = this.txtField2.Text;
this.Configuration.Field3 = this.txtField3.Text;
if(this.Configuration.Changed)
{
this.Configuration.Save();
this.OnConfigurationChanged(new ConfigurationChangedEventArgs(
this.Configuration));
}
this.Close();
}
}
catch(Exception ex)
{
this.OnUnhandledException(new UnhandledExceptionEventArgs(
"Failed To Apply Configuration Settings",
ex));
}
}
I'm currently testing out the code by breaking on the first line and stepping through the method line by line. Essentially, ValidateChildren is returning false as expected and the entire if block, including the this.Close() are skipped. Yet, if I step all the way to the bottom of the method and then step out of it I end up back on the frmSettingsForm.ShowDialog() line and the form is magically closed.
The "Apply" button is set as the form's AcceptButton. I wonder if it's implicitly attached a handler to the button's Click event to automatically close the form when the button is pressed. That doesn't sound like it logically should be assumed, especially considering there doesn't seem to be a way to cancel the Click event, but it's the only explanation that I can come up with. To test that theory, I have tried unsetting the AcceptButton in the designer, but my form still closes when the data is invalid.
What is closing my form and how do I stop it?
[1]: If anybody else has trouble finding it, it's a form property, not a property of each individual control (as I expected it would be).
Do you have the DialogResult of the Button set? If so, when you click the Button, the DialogResult of the Form will be set to that value and the modal Form will close. To prevent this, when validation fails in your Click handler, set the Form's DialogResult to DialogResult.None.
I don't know why that happens, but you could override the event OnFormClosing and check for the value of DialogResult according to your logic.
If (DialogResult != Windows.Forms.DialogResult.Cancel )
e.Cancel = True