DataGridViewのRowValidatingでフォーカス設定が効かない?

会社の後輩が悩んでたので、ちょっと調べてみた。


この「DataGridView」は、Web用ではなく「Windows.forms」のクラスである。
「RowValidating」イベントは、現在入力中のRow(行)から
フォーカスが外れると、当該イベントが発生する。


後輩は、このメソッドの中で、入力値の妥当性チェックを行い、
必要に応じてエラーメッセージを出力するという機能を実装していた。
実装は以下のような感じ。

private void DataGridView_RowValidating(object sender, DataGridViewCellCancelEventArgs e)
{
    if ((string)DataGridView.Rows[e.RowIndex].Cells[0].Value == "NG")
    {
        // エラーメッセージを表示
        MessageBox.Show("エラー");

        // キャンセルを有効       
        e.Cancel = true;
        
        // GridViewにフォーカスを設定
        DataGridView.Focus();
    }
}


しかし、エラーメッセージを出力し、メソッド内で「Focus()」を
呼び出しても、GridViewには、フォーカスが設定されなかった。
ちなみに、他のメソッドにおいては、フォーカスは正常に設定できる。


Webでググってみると、同じ悩みを持った人が多数いるようだ。
解決策は人によって、いろいろだが、これといった解決策は無いように思える。
その中で、「e.Cancel=true」が悪さをしていることまでは突き止めた。
実際、「e.Cancel=true」をコメント化して実行すると、正常にフォーカスが設定された。
(う〜む、なぜ・・・)


いろいろと検証してみる必要はあるが、必要に応じて「e.Cancel=true」を
呼び出さないという方法が現在の有力解決策である。
(別の問題が発生しそうな気がするが。)


最後に、個人的にこのメソッドの使用をお薦めしない。
というのも、フォーカスが外れた時点でチェック処理が実行されるので、
入力をやめて、画面を閉じようとするときでも処理が実行され、
エラーが表示されるので、ウザい。
そして、そんなにエラー処理の即時性が求められるとは思わない。
(リアルタイムで内容を反映するシステムなら別だが。)



最適な解決策を模索中なので、良い解決策が見つかったら記載します。