Strange behaviour with dialog box belonging to dialog box - c#

I have a form that I use the ShowDialog() method to bring up so the user can't change control back to the main form, and on the sub form I have a MessageBox.Show() method call which returns a DialogResult.
Only problem is, no matter what the dialog result of the message box, it causes my sub form to close. Is there a behaviour I am overlooking or is there something the matter with my code?
The code in the main form to open the sub form:
private void btnScanFree_Click(object sender, EventArgs e)
{
frmScan scanForm = new frmScan();
scanForm.ShowDialog();
}
And the code in the cancel button click method on the sub form:
private void btnCancel_Click(object sender, EventArgs e)
{
if (dgvScannedItems.RowCount > 0)
{
DialogResult dr = MessageBox.Show("There are scanned items that have not been inserted to the database. Are you sure you want to go back?", "Go Back", MessageBoxButtons.YesNo);
if (dr == System.Windows.Forms.DialogResult.Yes)
{
this.Close();
}
}
else
{
this.Close();
}
}
On the sub form, if there are no rows in the data grid view, then the form should close, otherwise a message box should appear with yes and no buttons and a question asking the user if they want to continue closing the form. But whether they press yes or no, it closes both the message box (which it always should) and the sub form (which half the time it should not).

BtnCancel is a dialog Button and sets DialogResult of the form to cancel or no or something similar. Since you have opened the form as a dialog via ShowDialog setting the DialogResult Causes the form to close and return the result.
So you need to set the DialogResult property of the BtnCancel to nothing to prevent this "starnge" behaviour.

Why not add a watch on dgvScannedItems.RowCount and see what the value is?

Related

How to prevent keystroke in child form reaching parent form?

I have a form that, upon user request, opens a child form, like so --
private void toolTrim_Click(object sender, EventArgs e)
{
Form form = new TrimOptions();
form.ShowDialog();
if (form.DialogResult == DialogResult.OK)
{
//code;
}
{
This child form has a button called btnOk and its property AcceptButton set to btnOk. This means that, when the Enter key is pressed in the child form, it's as if you had clicked on the Ok button, and this code executes.
private void btnOk_Click(object sender, EventArgs e)
{
Properties.Settings.Default.Save();
DialogResult = DialogResult.OK;
Close();
}
The problem is that, when the child form closes, the Enter key that was used to close the child form is captured by the DataGridView in the parent form.
private void filesDataGridView_KeyUp(object sender, KeyEventArgs e)
{
if (e.KeyCode == Keys.Return) //execution stops here if breakpointed
There's a legitimate use for that, but only when the DGV has focus, not when some child form of this form has focus.
So, how to prevent keystrokes in a child form from "bubbling up" to a parent form?
Following Steve's advice, I removed the Close(); having learned that setting DialogResult to any value other than None will close the window.
Following Hans Passant's advice to use KeyDown instead of KeyUp, I realized I had a mixture of KeyDowns and KeyUps. He was also correct, of course, that indeed the DGV had focus. I made them all KeyDowns, and my problem went away.
the other solution would be before opening modal you can disable the parent form once dialog is closed you can enable the parent form, so key up event does not fire.

WinForm closing when 'ok' is selected on messagebox

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)

Dialog in a Dialog window - Parent dialog closes with child dialog

In my main form I am opening a new form (lets call it the parent form) using ShowDialog(). In the parent form I have a button which loads an OpenFileDialog, when I load the image and click Open button, OpenFileDialog closes but it also closes the parent window and I dont want this to happen.
Main form code:
// ADD GRAPHICS BUTTON
private void bAddGraphics_Click(object sender, EventArgs e)
{
NewGraphics newGraphics = new NewGraphics();
newGraphics.ShowDialog();
if (newGraphics.DialogResult == DialogResult.OK)
{
Core.Graphics tempGraphicsObject = new Core.Graphics();
tempGraphicsObject.name = newGraphics.name;
tempGraphicsObject.background = newGraphics.bgImage;
core.NewGraphics(tempGraphicsObject);
generateSingleGraphicsControl(core.project.graphics[core.project.graphics.Count-1].id, core.project.graphics[core.project.graphics.Count-1].name);
}
newGraphics.Dispose();
}
Parent form(dialog)
OpenFileDialog openFileDialog = new OpenFileDialog();
DialogResult result = openFileDialog.ShowDialog();
if (result == DialogResult.OK)
{
tbBackground.Text = openFileDialog.FileName;
bgImage = Image.FromFile(tbBackground.Text);
}
openFileDialog.Dispose();
Is it because I use DialogResult twice or maybe because I call ShowDialog() in a dialog window ? If I won't use ShowDialog() on a parent but just Show() it works fine but then I can't use DialogResult property. Is there a way around it or you just can't use ShowDialog() twice ?
If the "parent" Form is closing too, then you're either calling Close() or setting the DialogResult property on the Form (which will also close it).
From MSDN, regarding the DialogResult property:
If the form is displayed as a dialog box, setting this property with a value from the DialogResult enumeration sets the value of the dialog box result for the form, hides the modal dialog box, and returns control to the calling form.
I don't see you doing either one of those in the code you posted, but check for a line like one of these in your "parent" Form:
DialogResult = DialogResult.OK;
this.DialogResult = DialogResult.Cancel;
Close();
this.Close();
I know I'm digging up an old post, but I just ran into this and found another situation that can cause this. It's common to copy/paste form controls and reuse them for other purposes. Make sure that if you copied your form's OK or Cancel button for the Browse File button that you remove the DialogResult value. I had done this and forgot to remove the DialogResult.OK from my folder browser button. Apparently, the DialogResult assignment will happen after the click event making it appear that the dialog closed its parent.

Using DialogResult Correctly

In an answer to a recent question I had (Here), Hans Passant stated that I should set the DialogResult to close my forms instead of form.Close() although I cannot seem to find out why?
If I've read correctly, the MSDN documentation states that doing this will just hide the form instead of correctly disposing it which I believed .Close() to do?
Extract from documentation.
The Close method is not automatically called when the user clicks the Close button of a dialog box or sets the value of the DialogResult property. Instead, the form is hidden and can be shown again without creating a new instance of the dialog box. Because of this behavior, you must call the Dispose method of the form when the form is no longer needed by your application.
On the other hand, Microsoft has created a support page that says how to use DialogResult property and in the "Verify It Works" section of this it states that clicking so will Close the form.
So my question is two fold, should I continue to use Close or DialogResult instead; and does dialog result close or hide a form. From the code I made below (a simple form with two buttons), it would seem that it is indeed hidden only as a breakpoint on this.Close() is hit..(with this.Close() commented, the form still disappears, just not sure whether hidden or not)
public Form1()
{
InitializeComponent();
button1.Click += (s, e) =>
{
//I edited my question to include using
using(Form1 form = new Form1())
{
form.ShowDialog();
}
};
button2.Click += (s, e) =>
{
this.DialogResult = DialogResult.OK;
this.Close();
};
}
When you open a modal dialog with ShowDialog, the calling code is blocked until the form called closes or hides. If you want to read some public properties of the called form and want to do things (for example save data to a database or to a file) based on the click on the OK or Cancel button, then you need to know if the user wants to do the action or not. The DialogResult returned by the ShowDialog() method allows you to take the appropriate actions...
So for example
using (Form1 form = new Form1())
{
DialogResult dr = form.ShowDialog();
if(dr == DialogResult.OK)
{
string custName = form.CustomerName;
SaveToFile(custName);
}
}
An important thing to add to this answer is the fact that the DialogResult property exists both on the Form class and in the Button class. Setting the button's DialogResult property (both via code or designer) to a value different from DialogResult.None is the key to activate an important behavior for forms. If you click a button with that property set then the Forms Engine transfers the value of the Buttons property to the Forms one and triggers the automatic closure of the form reactivating the caller code. If you have an event handler on the button click then you can run code to validate the form's inputs and force the form to stay open overriding the form's DialogResult property setting it back to DialogResult.None
For example, in the modally showed form you can have:
// Event handler for the OK button set with DialogResult.OK
public void cmdOK_Click(object sender, EventArgs e)
{
// Your code that checks the form data and
// eventually display an error message.
bool isFormDataValid = ValidateFormData();
// If data is not valid force the form to stay open
if(!isFormDataValid)
this.DialogResult = DialogResult.None;
}
Whether you call Close or set the DialogResult property is not really the issue. You just need to make sure to call Dispose. I prefer doing this with a using block:
using (Form1 form = new Form1())
{
form.ShowDialog();
}
I originally thought that you could call ShowDialog on a Form that has already had its Close method called. This is not the case. If you show the form modally with ShowDialog, it doesn't seem to matter whether it is closed as a result of the Close method, or setting the DialogResult property. It would seem that setting the DialogResult is just a short-cut for closing the Form.
But whether you call Close or set the DialogResult property, the key is to make sure that you call Dispose() or put your form in a using block.

Show a tooltip on the Close (X) button on the form

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?

Categories

Resources