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

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

ただいまの
回答率

90.76%

  • C#

    6562questions

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

BMI テキストボックスを小数点第一位まで入力を可能にする (小数点第二位からは入力させない)

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 260

xlostdjx

score 22

```C#
答えのあったページからコピペをし、変数などを揃えてビルドしても小数点が制御できません。
エラーもないのでどこがわるいのかわからなく困っています。

コード****

// 数値のみ小数点第一位まで入力が可能であること。
//----------------------------------------------------------------------------------------

//身長のテキストボックス入力時
private void textHeight_KeyPress(object sender, KeyPressEventArgs e)
{

//.KeyChar = 押されたキーに対応する文字を取得または設定します。
//数値と小数点とバックスペース以外の入力は不可
if ((e.KeyChar < '0' || e.KeyChar > '9') && e.KeyChar != '\b' && e.KeyChar != '.')
{

//.Handled = 取得またはを示す値を設定するかどうか、 KeyPress イベントが処理します。
e.Handled = true;
//e.Handled = Trueと入れると、キャンセルできる。
}
}

/*イベントが呼び出される順番が KeyDown→TextChanged→KeyUp なので
KeyDownイベントを使用します。*/

//DeleteキーやBackSpaceが押されたかどうかを判断。
bool isDelete = false;

private void textHeight_KeyDown(object sender, KeyEventArgs e)
{
isDelete = (e.KeyCode == Keys.Delete || e.KeyCode == Keys.Back);
}

//整数部桁数
private readonly int LENGTH_INT_PART = 7;
//小数部桁数
private readonly int LENGTH_DECIMAL_PLACES = 2;

private void textHeight_TextChanged(object sender, EventArgs e)
{
var txtBox = sender as TextBox;

txtBox.TextChanged -= textHeight_TextChanged;

try
{
if (!string.IsNullOrWhiteSpace(txtBox.Text))
{
var value = txtBox.Text;
//整数と小数を分割する
string[] values = value.Split('.');

int currentPoint = 0;
switch (values.Length)
{
case 1:

//------------------------------
//整数部のみで構成されている場合
//------------------------------
//整数部の最大桁数を超えた場合、今回の入力値を無効にする
if (value.Length > LENGTH_INT_PART)
{
//DELETEやBackSpaceによる削除で桁あふれが発生しているなら
//小数点の削除によるものなので、先頭桁から削除する
if (isDelete)
{
txtBox.Text = value.Substring(value.Length - LENGTH_INT_PART);

//カーソル位置を移動
if (currentPoint - (values.Length - LENGTH_INT_PART) >= 0)
{
txtBox.SelectionStart = currentPoint -
(values.Length - LENGTH_INT_PART);
}
else
{
txtBox.SelectionStart = 0;
}
}
else
{
//入力後の現カーソル位置を取得
currentPoint = txtBox.SelectionStart;

//カーソル位置の前の1文字が今回入力された文字、
//よって、それを省いた文字列に編集する
var left = value.Substring(0
, currentPoint > LENGTH_INT_PART
? LENGTH_INT_PART : currentPoint - 1);
var right = left.Length >= LENGTH_INT_PART
? "" : value.Substring(currentPoint);
txtBox.Text = left + right;

//カーソル位置を入力前の位置に戻す
txtBox.SelectionStart = currentPoint - 1;
}
}
break;

//--------------------------------------------------------------------------------------------------------------------------------------
case 2:

//----------------------------------
//整数部+小数部で構成されている場合
//----------------------------------
//入力後の現カーソル位置を取得
currentPoint = txtBox.SelectionStart;

//今回の入力値が"."の場合、小数点を基準点として桁あふれ分を除外する
if (value.Substring(currentPoint - 1, 1) == ".")
{
//=== 整数部の処理 ===
var intPart = values[0];
if (values[0].Length > LENGTH_INT_PART)
{
intPart = values[0].Substring(LENGTH_INT_PART - values[0].Length);
}

//=== 小数部の処理 ===
var decimalPart = values[1];
if (values[1].Length > LENGTH_DECIMAL_PLACES)
{
decimalPart = values[1].Substring(0, LENGTH_DECIMAL_PLACES);
}

//整数と小数を結合
if (values[0].Length > LENGTH_INT_PART || values[1].Length > LENGTH_DECIMAL_PLACES)
{
txtBox.Text = string.Format("{0}.{1}", intPart, decimalPart);

//小数点入力時なら小数点の後ろにカーソルをセット
txtBox.SelectionStart = value.IndexOf(".") + 1;
}
}
else
{
//=== 整数部の処理 ===
var intPart = values[0];
if (values[0].Length > LENGTH_INT_PART)
{
//カーソル位置の前の1文字が今回入力された文字、
//よって、それを省いた文字列に編集する
var left = values[0].Substring(0
, currentPoint > LENGTH_INT_PART
? LENGTH_INT_PART : currentPoint - 1);
var right = left.Length >= LENGTH_INT_PART
? "" : values[0].Substring(currentPoint);

//桁数調整後の整数部文字列
intPart = left + right;
}

//=== 小数部の処理 ===
var decimalPart = values[1];
if (values[1].Length > LENGTH_DECIMAL_PLACES)
{
//整数部と小数点を除いたときのカーソル位置を算出
var tempPoint = currentPoint - values[0].Length - 1;
//カーソル位置の前の1文字を除外する
var left = values[1].Substring(0
, tempPoint > LENGTH_DECIMAL_PLACES
? LENGTH_DECIMAL_PLACES : tempPoint - 1);
var right = left.Length >= LENGTH_DECIMAL_PLACES
? "" : values[1].Substring(tempPoint);

//桁数調整後の小数部文字列
decimalPart = left + right;
}

//整数と小数を結合
if (values[0].Length > LENGTH_INT_PART || values[1].Length > LENGTH_DECIMAL_PLACES)
{
txtBox.Text = string.Format("{0}.{1}", intPart, decimalPart);

//カーソル位置を入力前の位置に戻す
txtBox.SelectionStart = currentPoint - 1;
}
}

break;

default:
//"."で文字列を分割したときに3以上になるのなら、
//既に"."が存在しているのに今回"."が入力されたことを示す
//よって、今回の入力を無効にしてしまう。
{
currentPoint = txtBox.SelectionStart;
var left = value.Substring(0, currentPoint - 1);
var right = value.Substring(currentPoint);
txtBox.Text = left + right;
txtBox.SelectionStart = currentPoint - 1;
}
break;
}

//先頭が小数点なら先頭に 0 を入れる
if (txtBox.Text.StartsWith("."))
{
currentPoint = txtBox.SelectionStart;
txtBox.Text = "0" + txtBox.Text;
txtBox.SelectionStart = currentPoint + 1;
}
}
}
catch (Exception ex)
{
Console.Error.WriteLine(ex);
}
finally
{
txtBox.TextChanged += textHeight_TextChanged;
}

}

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • YAmaGNZ

    2018/05/29 09:40

    以前の質問で回答が得られてますが、何が理解できていないのでしょうか?

    キャンセル

  • xlostdjx

    2018/05/29 09:45

    小数点の指定がまだピンとこなく、、、回答をいただいたのを拝見してもどの部分が小数点を指定しているなどがわからなかったので 例文もしくはなにかしらコードで示していただけたらと思いまして。

    キャンセル

  • YAmaGNZ

    2018/05/29 11:50

    前回の質問でsaziさんの回答のリンク先にコードがありますが、こちらのコードを実装してデバッガで動作確認したりされましたか?そのコードに小数の桁制限の部分もありますので参考になりますよ。

    キャンセル

  • xlostdjx

    2018/05/30 10:42

    質問を編集したのでみてアドバイスいただきたいです。

    キャンセル

回答 2

checkベストアンサー

0

厳しいようですが、デバッガの使い方を勉強して、自分のプログラムがどう動いているか、ステップ実行するなりして確かめてください。
プログラムのデバッグを行う時に必要なことです。
初級者向けVisualStudio便利機能集Vol.2(デバッグ編)などを参照してください。

ヒント:
if (b.Length > 1)
これがどのように判定されるか確認してください。

 追記

下記のように、コードでイベントハンドラを登録するか

    textHeight.TextChanged += new System.EventHandler(textHeight_TextChanged);
    textHeight.KeyDown += new System.Windows.Forms.KeyEventHandler(textHeight_KeyDown);
    textHeight.KeyPress += new System.Windows.Forms.KeyPressEventHandler(textHeight_KeyPress);


下図のようにデザイナで登録するかしてください。
![イメージ説明](0988e08b74b6e76eac0f6d64984c6faa.png)

動作に関しては、関数入口にブレイクポイントを設定すれば、キー入力した時にそこで停止するはずです。
自分で書いたコードが動作しているのか、していないのか、動作している場合はなぜ思っている動きをしないのかを調査するために最低限必要なことです。
デバッガの使い方を勉強してください。動作を確認してください。としつこく言っているのはこういうことです。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/29 16:31

    if (b.Length > 1) は bに 165.5が入っていると仮定して .で区切られるので 
    165 と .5 配列が二つなので b には2が入っていることがわかりました。 

    ただ 
    数値とバックスペース以外の入力は不可にする事が適用されていないのはなぜかわかりません。
    お答えいただきたいです。

    キャンセル

  • 2018/05/29 16:39

    最初からテキストボックスに"165.5"と入っているということでしょうか?
    最初は「何も入力されていない」のでは?
    仮定ではなく、実際に動作させた時の値を確認しましょう。

    キャンセル

  • 2018/05/29 16:45

    実際に動かしても 下記のことがらは適用されませんでした。
    数値とバックスペース以外の入力は不可にする事が適用されていないのはなぜかわかりません。

    キャンセル

  • 2018/05/29 16:55

    if (b.Length > 1)
    ここにブレークポイントを張って、b.Lengthの値を確認しましたか?
    そこからステップ実行して、どのように実行されたか確認しましたか?

    キャンセル

  • 2018/05/29 17:49

    はい 確認しやり方を変えました。
    コードを編集しました、

    キャンセル

  • 2018/05/29 18:03

    b.Lengthが1以下の場合、チェックが走りませんがよいのですか?
    入力がなにもされていない場合や”1”の場合などだと1以下になりますよ?

    キャンセル

  • 2018/05/29 18:11

    はじめから一度 小数点第一位までを入力を可能にするコード書こうとおもいます
    これは理解するとかけるようになるなどあったら教えていただきたいです。
    もしよろしければ正解のコードを教えていただきたいです。
    ほぼコピペで組み立てていたので、。

    キャンセル

  • 2018/05/29 18:28

    前回の質問時にコードのあるページを回答してもらってるじゃないですか。
    適度にコメントもありますし、実際に動作させながら勉強すればよいかと思います。

    キャンセル

  • 2018/05/30 10:42

    質問を編集したのでみてアドバイスいただきたいです。

    キャンセル

  • 2018/05/30 10:57

    まず、「適用されません」というあいまいな表現はやめましょう。
    状況をなるべく具体的に説明するのも質問する時に重要なことです。
    今回の場合、「数字以外を入力できてしまう」とか書くべきです。

    次に、「数字以外が入力できてしまう」ということについてですが、
    参考にしたページにあったKeyPressイベントはどうして記述していないのでしょうか?

    キャンセル

  • 2018/05/30 11:06

    すみません。コピーが抜け落ちてしまっていました。
    KeyPressイベントをつけたしました。
    「数字以外が入力できてしまう」というのは反映されていて制御できているのですが、
    小数点の制限のところが反映されていないみたいです。

    キャンセル

  • 2018/05/30 11:12

    こちらで提示されたコードを動作させましたが、小数は1桁しか入力できません。
    小数点も1つだけ入力可能です。


    もしかして、コードをコピーしただけで、イベント登録してないということはありませんよね?
    デバッガで、イベント部分が呼び出されているか確認しましたか?

    キャンセル

  • 2018/05/30 11:19

    サイトでみて勉強したのですがいまいちイベントを理解していないです、なのでイベント登録できていないかもしれないです、
    イベント部分が呼び出されているかどうかの確認も、どれかわからないので困っています。

    キャンセル

  • 2018/05/30 11:29

    あ イベント意味の理解しました!!
    そしたら動くようになりました!!お手数かけてすみません。

    キャンセル

  • 2018/05/31 11:43

    あと
    ComboBox(丸め区分)をコード上で値の設定を行う事についてなんですけど
    おすすめのやり方をおしえていただきたいです。

    キャンセル

  • 2018/05/31 19:23

    それは複数質問を挙げることになってしまう為混乱を生んでしまうため本質問を解決済みにして新規で質問を立ち上げてください

    キャンセル

0

入力させない、ではなく、入力は自由にさせといて、Validateで小数点1位で取り込み、表示させるというのではダメでしょうか。
取り込み時にエラーが出たら、その旨表示し再入力させる、と。

初心者のうちはそのほうが簡単だと思いますよ


KeyPressでごそごそするというのはシュミでないんでちと考えてみました
直前の値を覚えておくためのtextval が必要なのがちとアレですが
あくまで一例ということで

using System.Text.RegularExpressions;


        string textval;
        // TextBoxのTextChange イベント
        private void txTextChange(object sender, EventArgs e)
        {
            TextBox tx = sender as TextBox;
            if (Regex.IsMatch(tx.Text, @"^\d*[.]?\d?$"))
            {
                textval = tx.Text;
            }
            else
            {
                tx.Text = textval;
            }
        }

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2018/05/29 09:28

    身長と体重の、テキストボックス入力時
    数値のみ小数点第一位まで入力が可能であること。
    バックスペースにて入力値が削除可能であること。= 数値とバックスペース以外の入力は不可
    という条件なのですが .Split 等を使って表した方がいいですか?

    キャンセル

  • 2018/05/29 09:36

    「c# 数値のみ」でぐぐって、これをアレンジしよう、ってことで

    キャンセル

  • 2018/05/29 14:19

    改善したコードを張ったのでみてほしいです。 また反映されないところがでてきたので

    キャンセル

  • 2018/05/29 15:45

    回答を更新しました

    キャンセル

  • 2018/05/29 15:50

    ご回答ありがとうございます、
    KeyPressを使用するのが条件でして、
    KeyPressバージョンをかいていただくことは可能でしょうか??

    キャンセル

  • 2018/05/30 10:42

    質問を編集したのでみてアドバイスいただきたいです。

    キャンセル

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

  • ただいまの回答率 90.76%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

  • 解決済

    jQueryで追加したテキストボックスにフォーカスしたい

    jqueryで、最後のテキストボックスに何か入力されたらもう一つテキストボックスを追加して、 そこにフォーカスするという動作の画面を作りたいと思っています。 テキストボックスの追

  • 受付中

    JavaScriptの綺麗なコードの書き方

    JavaScriptの綺麗なコードの書き方がわかりません。 例えば下記のような関数があった場合、皆さんならどのようにまとめますか?   function userLogin() {

  • 解決済

    ComboBoxの項目を表示させたいのですが・・・

    いつもお世話になっております。 ComboBoxの項目表示について質問させて頂きます。 本プログラムは「Enterキー」を押すと、フォーカスが移動し、 移動先の ComboBo

  • 受付中

    formをエンターで飛ばさない方法

    formを入力途中のエンターを押した時にsubmitさせない方法としてsubmit falsを書き込むのが有名ですが、 <input type="img" onClic="subm

  • 解決済

    contenteditableのdivタグ内の最初の一行をpタグに入れたい

    contenteditableなdivタグ内を改行の度にpタグにすることはできたのですが、最初の一行目だけはpタグに入りません。 ちなみにpタグに変更したのは下記を読み込む手法で

  • 解決済

    Enterキーだけが押されたときにイベントを発火させる方法

    Shift+Enterなどではイベントは発火せずに、Enterのみが押されたときにのみイベントが発生するようにしたいと思っています。 現状以下のようなものを作ってみたのですが

  • 受付中

    電卓について

    電卓を作っています。 キーボードからアルファベットを入力したとき Textboxにアルファベットが入力できないようにしたいです。 もしくは、数字だけ入力出来ないようにした

  • 解決済

    WPFのペースト処理で文字列編集しても反映されない。

    現象 クリップボードの文字列を取得し、その内容から数値のみを抽出。 抽出した文字列と元々入力されている文字列を結合したい。 例:テキストボックスに「9」が入力済み。 ク

同じタグがついた質問を見る

  • C#

    6562questions

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

  • トップ
  • C#に関する質問
  • BMI テキストボックスを小数点第一位まで入力を可能にする (小数点第二位からは入力させない)