C#で数値入力用のTextBox カスタムコントロールを作成してみる

ソフトを作ってるとTextBoxに数値だけを入力させたいときがあります。数値入力には、もともとNumericUpDowonというコントロールがありますが、見栄えや操作感から普通のTextBoxにしたいということもあるかと思います。
そこで今回は、VisualStudioの.NetFramework4.8 C# Windowsフォームアプリを利用して数値入力用のTextBoxをカスタムコントロールで作るやり方の覚書です。おそらく、.NET6.0などの.NET Core系のWindowsフォームアプリもほぼほぼ同じだと思います。最終的には、マイナスや小数点も入力できるコントロールにしていければと。

まずは、カスタムコントロールを作成する手順をざっと説明します。

ソリューションエクスプローラーのプロジェクトを右クリックして[追加]→[新しい項目]を選択します。

次の画面が小さい画面(コンパクトビュー)だった場合「すべてのテンプレートの表示」を選択します。

一覧から「カスタムコントロール」を探し、名前の欄に追加したいカスタムコントロールの名前を入力して「追加」を押します。

コードビューでコードを表示すると以下のようなひな形が入力されているので、継承元であるControlの部分をベースになるコントロールに書き換えます。今回はTextBoxのカスタムコントロールを作りたいのでTextBoxと打ち直します。

ここまでできたら、いったんリビルドして、Formのデザインビューを表示するとツールボックスに今作ったTextBoxNumExというコントロールが追加されているのがわかります。

あとは、さっきのTextBoxNumEx.csのコードビューに処理を追加していく流れになります。

では、実際にコードを追加してみます。次のOnKeyPressのメソッドを追加します。おそらく、VisualStudio2022だと、ちょっと入力するだけでインテリセンスで候補が出てきて、簡単に入力できると思います。ひな形に元々あったoverride OnPaintのメソッドは今回は使わないので削除してしまっても大丈夫です。

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 TextBoxExTest
{
    public partial class TextBoxNumEx : TextBox
    {
        public TextBoxNumEx()
        {
            InitializeComponent();
        }

        protected override void OnKeyPress(KeyPressEventArgs e)
        {
            //一旦すべてのKeyPressを無効にする
            e.Handled = true;

            //数字は有効に戻す
            if ('0' <= e.KeyChar && e.KeyChar <= '9')
            {
                e.Handled = false;
            }

            //バックスペースは有効に戻す
            if (e.KeyChar == '\b')
            {
                e.Handled = false;
            }

            base.OnKeyPress(e);
        }
    }
}

こうすることで、テキストボックスは数字かバックスペースしか受け付けなくなります。(deleteキーはOnKeyPressが呼ばれないので効きます。)ただ、これだけではマイナスや小数点の数値が入力できなかったり、Ctrl+cやvが使えなくて使いづらかったり、マウスで数字以外がペーストできてしまったりするので問題があるかもしれません。。やり方としては、こんな感じで独自の機能を拡張していきます。

最後に色々な機能を組み込んでみた数値入力用のカスタムコントロールのサンプルを張り付けておきます。例えば下記ような機能が入っています。

■追加してみた機能
・数値に変換できない場合は背景色を変える
・入力可能最大値、最小値のプロパティ設定(ExMaximum、ExMinimum)の追加
・小数点以下の桁数のプロパティ設定(ExDecimalPlaces)の追加
・マイナスの入力可否のプロパティ設定(ExEnableMinus)の追加
・入力されたdecimal型数値を読みだす専用の(ExValue)の追加

コメント