AutoValidate

7/1のエントリで言及したCausesValidationの振る舞いに一貫性が無い件に関して、私はCausesValidationの振る舞いに固執していたが、いろいろと調べてみると、名無しさんのコメントにあるように、FormのAutoValidateプロパティが優先するのが根本の原因のようだ。

                                                      • -
C#
                                                      • -
public enum AutoValidate
                                                      • -
コントロールにユーザー入力フォーカスがなくなったときのコントロールの検証方法を決定します。
  • Disable 暗黙的な検証は発生しません。この値を設定しても、Validate または ValidateChildren の明示的な呼び出しには影響ありません。
  • EnableAllowFocusChange 暗黙的な検証が発生しますが、検証が失敗した場合も、フォーカスは新しいコントロールに移ります。検証が失敗した場合、Validated イベントは発生しません。
  • EnablePreventFocusChange コントロールにフォーカスがなくなると、暗黙的な検証が発生します。
  • Inherit コントロールは、そのコントロールのコンテナ (フォームや他のコントロールなど) から AutoValidate 動作を継承します。コンテナ コントロールがない場合、既定値は EnablePreventFocusChange です。

このプロパティのデフォルトはAutoValidate.EnablePreventFocusChangeで、コントロールに入力フォーカスがなくなると、暗黙的な検証が発生するのが当たり前の振る舞いとなっており、FormがCloseする際には、このルールがそのまま適用されるようだ。(ソースコードが無いのでこれも推測だが...)
従って最も合理的な解決方法は、名無しさんがサンプルで書いたとおり、

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

とするのが良いと思う。CausesValidationとは関係の無い振る舞いは仕様なのだろう。

とはいうものの、直感的ではないし、CausesValidationをfalseにセットしたボタンで、Closeメソッドを実行したときのValidatingイベントの問題はnewsを初めとして至るところで散見されるので、FAQとして、AutoValidateプロパティとの関係を明記すれば良いのになと思う。