web-dev-qa-db-ja.com

WPFテキストボックスでの数値入力のみを許可する

ユーザーエントリを検証して、それらが整数であることを確認します。どうすればできますか? IDataErrorInfoを使用することを考えました。これは、WPFで検証を行うための「正しい」方法のようです。それで、ViewModelに実装してみました。

しかし、私のテキストボックスは整数フィールドにバインドされており、intintであるかどうかを検証する必要はありません。 WPFがテキストボックスの周囲に赤い境界線を自動的に追加して、ユーザーにエラーを通知していることに気付きました。基になるプロパティは無効な値に変更されません。しかし、これをユーザーに通知したいと思います。どうすればできますか?

13
Jiew Meng

表示されている赤い境界線は実際にはValidationTemplateであり、これを拡張してユーザーの情報を追加できます。この例を参照してください。

    <UserControl.Resources>
        <ControlTemplate x:Key="validationTemplate">
            <Grid>
                <Label Foreground="Red" HorizontalAlignment="Right" VerticalAlignment="Center">Please insert a integer</Label>
                <Border BorderThickness="1" BorderBrush="Red">
                    <AdornedElementPlaceholder />
                </Border>
            </Grid>
        </ControlTemplate>
    </UserControl.Resources>

<TextBox Name="tbValue" Validation.ErrorTemplate="{StaticResource validationTemplate}">
12
Andrei Pana

もう1つの方法は、整数以外の値を許可しないことです。次の実装は少し厄介です。後で再利用できるように抽象化したいと思いますが、これが私がしたことです。

私の見解の背後にあるコードで(あなたが筋金入りのmvvmである場合、これは害を及ぼす可能性があることを私は知っています; o))私は次の関数を定義しました:

  private void NumericOnly(System.Object sender, System.Windows.Input.TextCompositionEventArgs e)
{
    e.Handled = IsTextNumeric(e.Text);

}


private static bool IsTextNumeric(string str)
{
    System.Text.RegularExpressions.Regex reg = new System.Text.RegularExpressions.Regex("[^0-9]");
    return reg.IsMatch(str);

}

また、XAMLビューでは、整数のみを受け入れることになっているすべてのテキストボックスが次のように定義されています。

   <TextBox Padding="2"  TextAlignment="Right" PreviewTextInput="NumericOnly" Text="{Binding xxx.yyyy}" MaxLength="1" />

PreviewTextInputであるキー属性

14

テキストボックスの変更されたイベントの検証を行うことができます。次の実装は、数値と小数点1桁以外のキー入力を防ぎます。

private void textBoxNumeric_TextChanged(object sender, TextChangedEventArgs e)
{
        TextBox textBox = sender as TextBox;
        Int32 selectionStart = textBox.SelectionStart;
        Int32 selectionLength = textBox.SelectionLength;
        String newText = String.Empty;
        int count = 0;
        foreach (Char c in textBox.Text.ToCharArray())
        {
            if (Char.IsDigit(c) || Char.IsControl(c) || (c == '.' && count == 0))
            {
                newText += c;
                if (c == '.')
                    count += 1;
            }
        }
        textBox.Text = newText;
        textBox.SelectionStart = selectionStart <= textBox.Text.Length ? selectionStart : textBox.Text.Length;    
}
8
kumar Gouraw

wPFで作業している場合は、すべてのプラットフォームとpresentationcore.dllをサポートするPreviewTextInputイベントを使用することをお勧めします

次に例を示します。

private void TextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
    {
        if ((e.Text) == null || !(e.Text).All(char.IsDigit))
        {
            e.Handled = true;
        }
    }
0
Gaurav Panwar