例えば
入力された内容が半角数字のみかどうかを、テキストボックスの `Validating` メソッドで調べたい。
もし、
* 半角数字以外の文字が含まれている
* 未入力
である場合は、テキストボックスにフォーカスを当てたままにする。
という実装をするとする。実装すると以下のようになる。
この場合、フォームが未入力な状態で他のボタンを押そうとすると、フォーカスイベントにより、フォーカスがボタンに移るより前にテキストボックスの Validating
メソッドが働いてしまい、別のコントロールに遷移するのはもちろん、ボタンを押すこともできなくなる。
では、テキストボックスが不完全 or 未入力な状態であっても、終了ボタンを押したときだけ Validating
メソッドを無視してフォームを閉じるようにするにはどうすればよいか? というのが今回の内容です。
方法その1:CausesValidationプロパティ
終了ボタン側の CausesValidation
プロパティを false
にする。
// 終了ボタン
ExitFormButton.CausesValidation = false;
CausesValidationプロパティの説明は以下のとおりです。
そのコントロールが原因で、フォーカスを受け取ると検証が必要なコントロールに対して、検証が実行されるかどうかを示す値を取得または設定します。
そして注釈には
プロパティが CausesValidation に false設定されている場合、 Validating イベントと Validated イベントは抑制されます。
とあります。
おそらく、.CausesValidation = false
であるコントロールをフォーカスしようとすると、それまでフォーカスが当たっていたコントロールの Validating
メソッド、あるいは Validated
メソッドは無視してフォーカス遷移する、ということかと思われます。
便利なプロパティに思えますが、.NETFrameworkにおけるフォーカスイベントの流れを理解していないと「なんのこっちゃ」となってしまいそうです。
方法その2:ActiveControl
ActiveControl
が終了ボタンに移っているかどうかで処理を分岐させる。
// テキストボックスのValidatingメソッド
if (this.ActiveControl.Name == ExitFormButton.Name) // ActiveControlのNameと終了ボタンのNameで判定
{
// ActiveControlが終了ボタンに移っているためなにもしない
return;
}
else
{
// テキストボックスのValidating処理
}
ActiveControl
はコントロールにフォーカスを当てる機能を提供する ContainerControl
クラスのプロパティで、現在フォーカスを当てているコントロールの情報を保持しています。
通常のコントロールと同様に Name
プロパティでコントロール名を取り出せるので、上の例ではコントロール名を条件分岐に用いています。
コントロール名が同じ、つまりアクティブなコントロールが終了ボタンに移っていれば、テキストボックスの Validating
メソッドの処理内容を無視して終了ボタンにフォーカスする、それ以外は Validating
メソッドの処理内容を適用する、というかたちです。
コード量はやや多くなりますが、CausesValidation
プロパティを使う方法に比べてコントロールの機能がわかりやすいのではないかとおもいます。