Why is the Validated event not triggered for controls in the form created in the main form when the child form is closed?

Let's say I have a winforms application with two forms, the main form that starts when the program starts, and another form. Here is the code for the main form:

public partial class Form1 : Form { public Form1() { InitializeComponent(); } private void button1_Click(object sender, EventArgs e) { var f2 = new Form2(); f2.ShowDialog(); } private void textBox1_Validated(object sender, EventArgs e) { System.Diagnostics.Debug.Print("Main Form: Validated!"); } } 

And this is the child form:

 public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void textBox1_Validated(object sender, EventArgs e) { System.Diagnostics.Debug.Print("Child Form: Validated!"); } } 

When I launch the application, I can put the focus in the text box in the main form, and of course, when I go to the tab, it fires the Validated event and prints Main Form: Validated! at the exit. This also happens if I have focus in the text box and closing the main form (i.e. terminating the program).

When I click on the button in the main form that issues an instance of the child form, I can put the focus in the text box on the child form, and the Validated event fires, as it should when I exit This. However, unlike the behavior of the main form when closing the form, if I have focus in the text box on the child form and I close the child form, the Validated event never fires.

Why the activated fire of events does not work, and is there a way I can launch it.

I rely on the checked event of certain controls to update my view models. I want to make sure that they always work, even when the loss of focus is associated with closing the form or even ending the application itself.

+5
source share
4 answers

This is called ShowDialog (). This is a documented bug, a bug in .NET 1.x that they can no longer fix. From the source code of the form :

  // NOTE: We should also check !Validate(true) below too in the modal case, // but we cannot, because we didn't to this in Everett (bug), and doing so // now would introduce a breaking change. User can always validate in the // FormClosing event if they really need to. :-( 

So just follow the directions:

  protected override void OnFormClosing(FormClosingEventArgs e) { if (e.CloseReason == CloseReason.UserClosing && this.DialogResult != DialogResult.Cancel) { if (!base.Validate(true)) e.Cancel = true; } base.OnFormClosing(e); } 

With the assumption that you do not need an event when the dialog is rejected, and you want the dialog to remain open when the validation fails. The last point is a new behavior.

+10
source

The documentation says:

Unlike modeless forms, the Close method is not called by .NET. Structure when the user clicks the close button on the form of the dialog box or sets the DialogResult property. Instead, the form is hidden and can be shown again without creating a new instance of the dialog box.

Based on documents, when you call the ShowDialog method of the second form ( Form2 ), and you close it by clicking on the close button (the button with the X in the upper right corner of the form), the form is hidden (not closed ). This is why the Validated event never fires.

Note: Closing and Closed events will fire anyway.

Note2: Closing the form with ALT + F4 same as pressing the X button on the form.


Demonstration

Form as modal (your example)

The second form opens by calling ShowDialog . Add a button to the second form and set the click event as follows:

 private void button1_Click(object sender, EventArgs e) { this.Close(); } 

If you close the form by clicking this new button, the Validated event will occur. If you close the form by clicking the button with the X in the upper right corner of the form, the Validated event will not fire (because the form never closes, it is hidden).

Form as modeless

The second form opens by calling Show . In this case, when you click the button with X in the upper right corner of the form, the latter will be really closed (not hidden), and the Validated event will fire.


Bypass

Hiding ControlBox

The easiest way is to hide the X button of the form by setting the ControlBox property to false (by design or by code). However, the user can close the form using ALT + F4 .

Using Hans Passant Solution

Hope that will be clear.

+4
source

If you want, all of your modal dialog controls are checked at close. You can probably get closer below ... which definitely triggers an event acknowledged by a text box.

Add an event to close the form in Form2 and call ValidateChildren()

 private void Form2_FormClosing(object sender, FormClosingEventArgs e) { this.ValidateChildren(); } 
+1
source

MSN Documentation

According to MSN documentation. If the CausesValidation property is false, Validating and Validated events are suppressed.

Checks the value of focus control loss by raising Validating and Validated: events according to MSN documentation

You can also activate validation and event validation using the Validate () method, which loses control focus. That way, you can call the Validate method to close the Form2 event. Below is the code

 public partial class Form2 : Form { public Form2() { InitializeComponent(); } private void textBox1_Validated(object sender, EventArgs e) { System.Diagnostics.Debug.Print("Child Form: Validated!"); } private void Form2_Closing(object sender, FormClosingEventArgs e) { if (!Validate()) //Write your code that will execute if your form is not validated } } 
+1
source

Source: https://habr.com/ru/post/1274078/


All Articles