質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.47%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

Q&A

解決済

2回答

1560閲覧

テキストボックスに禁止文字を設定して、入力されてもテキストボックスに入力を反映させないようにする

fishkajiki_0423

総合スコア1

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

Visual Studio

Microsoft Visual StudioはMicrosoftによる統合開発環境(IDE)です。多種多様なプログラミング言語に対応しています。

.NET Framework

.NET Framework は、Microsoft Windowsのオペレーティングシステムのために開発されたソフトウェア開発環境/実行環境です。多くのプログラミング言語をサポートしています。

0グッド

0クリップ

投稿2023/09/19 07:29

実現したいこと

テキストボックスに、±を含むfloat型の数値のみを入力可としたいです。

  • ▲▲機能を動作するようにする

前提

Visual Studio Professional 2022(Version 17.7.2)、.NET Framework(Version 4.8.09032)を使用して、テキストボックスなどを使用した機械操作用インターフェースアプリを開発しています。その画面内でユーザが、各種条件を入力するためのテキストボックスに入力ミス防止機能を付属させることが目的です。

発生している問題・エラーメッセージ

IMEModeプロパティはDisableなので、日本語入力はできないようにしています。また、アルファベットなどの文字入力はKeyPressイベントに禁止文字入力を阻止するメソッドを追加することで達成できています。
しかし、float型変数になり得ない状況が防げません。
(例:45.1.5 ← 小数点が2つ存在する。12-3.456 ← マイナス符号の位置が不正)

該当のソースコード

C#

1 private void KeyPressCheck(object sender, KeyPressEventArgs e) 2 { 3 if (e.KeyChar != '.'& e.KeyChar != '\b' & e.KeyChar!='-') 4 { 5 if (e.KeyChar < '0' || e.KeyChar > '9') 6 { 7 //var sample = e.KeyChar; 8 e.Handled = true; 9 } 10 } 11 if (float.TryParse(Txt1.Text.ToString(), out float fval) == false) e.Handled = true; 12 } 13

試したこと

最初に試した、Maskedtextboxのマスク機能は入力時に桁の指定までされてしまうため、使いづらいと社内の評価会で却下されてしまいました。
次に、KeyPressイベントにて
if (float.TryParse(Txt1.Text.ToString(), out float fval) == false)e.Handled = true;
を仕込んで試したのですが、不正な入力ができてしまう上にDeleteキー以外での修正も効かなくなってしまいます。どのようにしたら、数値として認識できない入力をテキストボックスに反映させずに阻止できるか、お知恵を貸してください。

補足情報(FW/ツールのバージョンなど)

Visual Studio Professional 2022(Version 17.7.2)
.NET Framework(Version 4.8.09032)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KOZ6.0

2023/09/19 16:10

回答にも書きましたが、TextBox 前提にどうこうするのはとても大変です。 機械制御の画面であれば、デフォルトの設定値があって、そこからプラスマイナスして調整するでしょうから NumericUpDown は扱いやすいと思います。
guest

回答2

0

ベストアンサー

YAmaGNZ さんが回答されてますが、KeyPress イベントでは Text プロパティに反映されていません。
SelectionStart プロパティと、SelectionLength プロパティを使って、左と右にテキストを分けてください。

csharp

1protected void GetUnSelectedText(out string left, out string right) 2{ 3 string prevText = base.Text; 4 left = prevText.Substring(0, SelectionStart); 5 right = prevText.Substring(SelectionStart + SelectionLength); 6}

通常文字を入力すると、反映された後のテキストは 左 + 入力文字 + 右 になります。
原則として、反映された後、テキストがどうなるかを予測してチェックします。

数値チェックについては Decimal.TryParse を使ったほうがいいのではないでしょうか。
先頭か後ろにしか符号を入力できなくする手もあります。

また、数値の場合、"." を消してしまうと、"1.000" → "1000" になってしまうので注意が必要です。
"." を消したら、右側をクリアするといいかもしれません。


考慮しなければいけないのは、数字や記号だけではありませんし、ウインドウメッセージにも注意する必要があります。

1.考慮するキャラクタ

(1) BackSpace

選択している文字がある場合、選択された文字列が消えます。選択する文字が無い場合は、現在のカーソルの左1文字が消えます。

(2) CTRL+A(全選択)

そのまま通します。

(3) CTRL+C(COPY)
テキストが変わらないのでそのまま通します。

(4) CTRL+V(PASTE)
コンテキストメニューから貼り付けできるため、WM_PASTE をキャッチして処理したほうが良いです。

(5) CTRL+X(CUT)
コンテキストメニューから切り取りできるため、WM_CUT をキャッチして処理したほうが良いです。

(6) CTRL+Z(UNDO)
コンテキストメニューから元に戻せるため、WM_UNDO をキャッチして処理したほうが良いです。
ただし、UNDO 後のテキストを予測するのは困難なため、禁止(無視)したほうが良いかもしれません。

(7) Delete

選択している文字がある場合、選択された文字列が消えます。選択する文字が無い場合は、現在のカーソルの右1文字が消えます。
ただし、これは OnKeyPress には入ってこないので、OnKeyDown で処理してください。

2.考慮するウインドウメッセージ

(1) WM_CUT/WM_CLEAR

選択された文字列が消えます。

(2) WM_PASTE

選択された文字列が消え、クリップボードの内容に置き換わります。
1文字ずつ加えていき、チェックします。

(3) WM_UNDO/EM_UNDO
さきほど触れましたが禁止したほうがいいかもしれません。
WndProc を呼んで、反映した後チェックし、不都合があれば元に戻すという荒業もありでしょうか。

こんなところですかね・・・

入力制限の処理は大変です。
機械制御系の画面だと、NumericUpDown を使っているのをよく見ますよ。

投稿2023/09/19 09:06

編集2023/09/19 16:18
KOZ6.0

総合スコア2626

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fishkajiki_0423

2023/09/19 23:17

早速のご返答ありがとうございます。NumericUpDownという存在を知らなかったので、これから調べて試してみます。 また、私の想定できていない入力までご紹介いただきまして重ねてお礼申し上げます。
fishkajiki_0423

2023/09/20 00:50

いただいたサンプルコードを基に、実装したところ想定通りの挙動で入力チェックができました! NumericUpDownコントロールはオフセット入力用のテキストボックスとの代替を検討してみます。 改めましてご回答いただきました皆様、ありがとうございました。
guest

0

KeyPressイベントにてTxt1.Textを取得しても入力したキーの文字はまだ反映されていない状態です。
なので、Txt1.Textに入力した文字を反映した状態でfloatかチェックする必要があるかと思います。

また、入力途中を考えると”-”や””などTryParseでfalseになる場合でもOKにしたりと処理が必要かと思います。
ついでに”-.1”といったTryParseでtrueとなるものはどうするのかも考慮が必要になってくるかと思います。

投稿2023/09/19 07:53

編集2023/09/19 08:09
YAmaGNZ

総合スコア10258

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

fishkajiki_0423

2023/09/19 23:13

早速のご返答ありがとうございます。”-.1”がTryParseでtrueになってしまうとは知りませんでした。 入力確定後の計算などにもTryParseを使用してチェックを行う箇所があったので、参考になりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.47%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問