how to detect a button click from another form - c#

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;

Related

Parent Dialog Closes When Child Dialog is Closed

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

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)

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.

dialogresult does not work or partially work for some reason

I made a form to be a dialog and the form only has one textbox, one OK button and one Cancel button. somehow, when the following does not work unless i change rnmForm.DialogResult!=DialogResult.OK), why is that????
frmRename rnmForm = new frmRename();
rnmForm.ShowDialog(new Form());
if (rnmForm.DialogResult==DialogResult.OK)
{
MessageBox.Show("test");
}
Did you make sure to set the dialog result to OK, before you close the dialog in the Ok click event?
this.DialogResult = DialogResult.OK;
this.Close();
Or setting the property on the Ok button, similar to this:
btnOk.DialogResult = DialogResult.OK;
I also have to ask why you are calling showDialog and specifying a new instance of your form to be the owner, instead of just calling it with no parameters. Just not sure that was intentional.
rnmForm.ShowDialog();

DialogResult that doesn't close the form?

I have a form Form1 from which I display Form2 as a modal form. From Form2 I do all sort of editing and deleting of different set of values which should be reflected in Form1 after closing Form2. So what I do is RePopulateControls_in_Form1() after closing Form2. Since RePopulateControls_in_Form1()is a long process, I want to execute that method only if some modification (edit,add, delete) happens in Form2 and not when Form2 is just opened and closed.
So this is what I try to do in Form1:
Form2 f = new Form2();
if (f.ShowDialog(this) == DialogResult.Something)
RePopulateControls_in_Form1()
And then in Form2 I do,
private void bntEdit()
{
//If Edit?
this.DialogResult = DialogResult.Something;
}
private void bntAdd()
{
//If Add?
this.DialogResult = DialogResult.Something;
}
private void bntDelete()
{
//If Delete?
this.DialogResult = DialogResult.Something;
}
But my problem is .Something. If it is anything other than .None, Form2 simply gets closed. I do not want Form2 to get simply closed by its own unless the user closes it.
If I do this:
//in Form1
private void Form1_Click()
{
Form2 f = new Form2();
if (f.ShowDialog(this) == DialogResult.None)
RePopulateControls_in_Form1()
}
//in Form2
private void Form2_SomeModification()
{
//If Modified?
this.DialogResult = DialogResult.None;
}
RePopulateControls_in_Form1() is not hit!
In short, in my program how can I tell the compiler to call RePopulateControls_in_Form1() only if values are modified in Form2?
Note: Repopulating is certainly required since the controls are dynamically created and a bit complex (actually what is created in Form2 is GUI controls and its labels etc).
Setting DialogResult on Form hides the form and returns from ShowDialog. If you want to delay that until the user performs some other action (such as closing the form) you should store that state as a member field and set DialogResult in a handler for Form.Closing.
Also, if you do want to dismiss the modal form on a button press, you can use the Button.DialogResult property instead of making a Button.Click handler.
A simple way might be not to use DialogResult at all but a dedicated property not interfering with the Form's behavior. - Then you should be able to program any logic you want.
I would use an event in Form 2. Fire that event when your Form2 is closing. Handling that event in Form1 would allow you to carry out any processing you want to. Further if needs be you could pass back some information from Form2 to Form1 in parameters to the event.
An alternative would be to set up a Global static variable - maybe just a bool. Then Form2 can set it to true or false depending on whether there are changes made. Form1 can read this when Form2 returns and if true carry out processing and set it back to false.

Categories

Resources