C#Windowsフォームプログラミング備忘録

Validatingイベントハンドラがある時のフォームのクローズ

C#

Windowsフォームアプリケーションを作成しているとValidatingイベントで入力値の妥当性チェックをしたいが、閉じるボタンや×ボタンを押した時は何もせずそのままフォームを閉じたいことがある。

上のフォーム画面のtextBox1に数値が入力されているかチェックし、数値以外だった場合はメッセージダイアログを表示しフォーカスをtextBox1から移動しないようにしたい。このようなときはtextBox1のValidatingイベントを処理すればよい。ただし、閉じるボタンbutton1と×ボタンを押した時はtextBox1に数値以外の値が入力されていてもそのままフォームを閉じられるようにしたい。

以下のコードで対処した。

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;

namespace ValidatingEventTest
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void textBox1_Validating(object sender, CancelEventArgs e)
        {
            int i;
            string textValue = textBox1.Text;
            bool result = int.TryParse(textValue, out i);

            if (!result
                && this.ActiveControl != button1 //① 閉じるボタンを押した時にフォームを閉じられるようにする
                && this.ActiveControl != textBox1) //② ×ボタンを押した時にフォームを閉じられるようにする
            {
                MessageBox.Show("数値を入力してください");
                e.Cancel = true; //③ フォーカスを移動させないようにする
            }
        }

        /// <summary>
        /// 閉じるボタンの処理
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            this.Close();
        }
    }
}

(処理1)テキストボックスに数値が入力されているかチェックし、数値でなければメッセージダイアログを表示してフォーカスを移動しないようにする

上記ソースコードのコメント①について
textBox1にフォーカスがある状態で閉じるボタンを押すと、アクティブコントロールは閉じるボタンになるので閉じるボタンでない時だけ(処理1)を行えばよい。

上記ソースコードのコメント②について
textBox1にフォーカスがある状態で×ボタンを押すと、アクティブコントロールはtextBox1のままになるのでtextBox1でない時だけ(処理1)を行えばよい。

試しにtextBox1にアルファベットを入力してタブやマウスクリックでtextBox2にフォーカスを移動しようとすると、メッセージダイアログが表示されてフォーカスはtextBox1のままとなる。一方、textBox1にアルファベットが入力されていても閉じるボタンや×ボタンを押すとそのままフォームは閉じられる。

検証環境

Microsoft Visual Studio Community 2022 (64 ビット) Version 17.2.6

.NET Framework 4.8

コメント

  1. あばば無人君 より:

    閉じるボタン(button1)は CausesValidation プロパティをfalseにしておけば
    if文チェックは不要かも!?

    • 棒 より:

      あばば無人君さん、コメントありがとうございます。

      実は業務で書いていたプログラムが上のサンプルプログラムよりも複雑で CausesValidation プロパティで上手く対応できなかったため、上記のコードで対処しました。やはり業務の方もCausesValidationで対応できないか再度考えてみます。
      ありがとうございました。