TextBoxでWPFの数値入力のみを受け付けるにはどうすればよいですか?


334

数字と小数点を受け入れようとしていますが、符号はありません。

Windowsフォーム用のNumericUpDownコントロールを使用したサンプルと、MicrosoftのNumericUpDownカスタムコントロールのこのサンプルを見てきました。しかし、これまでのところ、NumericUpDown(WPFでサポートされているかどうかにかかわらず)では必要な機能が提供されないようです。私のアプリケーションの設計方法では、右心の誰も矢印をいじりたくありません。私のアプリケーションのコンテキストでは、それらは実用的な意味を持ちません。

したがって、標準のWPF TextBoxに必要な文字だけを受け入れる簡単な方法を探しています。これは可能ですか?それは実用的ですか?

回答:


417

プレビューテキスト入力イベントを追加します。のように:<TextBox PreviewTextInput="PreviewTextInput" />

次に、その中にe.Handledテキストが許可されていない場合のセット。e.Handled = !IsTextAllowed(e.Text);

IsTextAllowedメソッドで単純な正規表現を使用して、入力した内容を許可する必要があるかどうかを確認します。私の場合、数字、ドット、ダッシュのみを許可します。

private static readonly Regex _regex = new Regex("[^0-9.-]+"); //regex that matches disallowed text
private static bool IsTextAllowed(string text)
{
    return !_regex.IsMatch(text);
}

誤ったデータの貼り付けを防止したい場合は、次のようにDataObject.PastingイベントDataObject.Pasting="TextBoxPasting"をフックアップします(抜粋したコード)。

// Use the DataObject.Pasting Handler 
private void TextBoxPasting(object sender, DataObjectPastingEventArgs e)
{
    if (e.DataObject.GetDataPresent(typeof(String)))
    {
        String text = (String)e.DataObject.GetData(typeof(String));
        if (!IsTextAllowed(text))
        {
            e.CancelCommand();
        }
    }
    else
    {
        e.CancelCommand();
    }
}

5
正規表現では、科学的表記(1e5)が重要な場合は許可されません。
ロンウォーリック

14
この回答は入力した内容のみをチェックするため、3-.3と入力できます
David Sykes

153
答えの要点は、完全な正規表現を指定することではなく、WPFを使用してユーザーが入力したものをフィルタリングする方法を示すことでした。
レイ

27
[スペース]はPreviewTextInputイベントを発生させません。
peterG 2014年

5
のようなものdouble.TryParse()はおそらく同じ行数で実装され、より柔軟になります。
トーマスウェラー2017年

190

イベントハンドラがテキスト入力をプレビューしています。ここで、正規表現は、それが数字ではない場合にのみテキスト入力と一致し、その後、テキストボックスへの入力は行われません。

文字だけが必要な場合は、正規表現をに置き換え[^a-zA-Z]ます。

XAML

<TextBox Name="NumberTextBox" PreviewTextInput="NumberValidationTextBox"/>

XAML.CSファイル

using System.Text.RegularExpressions;
private void NumberValidationTextBox(object sender, TextCompositionEventArgs e)
{
    Regex regex = new Regex("[^0-9]+");
    e.Handled = regex.IsMatch(e.Text);
}

1
イベントハンドラーはプレビューテキスト入力です。ここで、正規表現は、それが数値でない場合にのみテキスト入力と一致し、その後、入力テキストボックスには行われません。アルファベットのみが必要な場合は、正規表現を[^ a-zA-Z]に置き換えます。
Kishor

数値、小数、演算子についてはどうですか?
Jason Ebersey 2013年

他の静的クラスで宣言し、テキストボックスに適用する場合の使用方法を教えてください。
SHEKHAR SHETE 2013年

3
私はこれを実際の答えよりも気に入っています。短くてシンプルです。実際の答えでは、同じ結果を得るには2つの方法が必要です。
スライバー、2015

1
@Jagd提案された答えは、懸念の分離の改善です。ただし、この検証ではテキストボックスをいくつでも設定できます。PreviewTextInput = "NumberValidationTextBox"を追加するだけです。(他の答えと同じように!)
スリヴァー

84

私はすでにここにあるもののいくつかを使用し、ビヘイビアーを使用して独自のひねりを加えたので、このコードをビューのトン全体に伝播する必要はありません...

public class AllowableCharactersTextBoxBehavior : Behavior<TextBox>
{
    public static readonly DependencyProperty RegularExpressionProperty =
         DependencyProperty.Register("RegularExpression", typeof(string), typeof(AllowableCharactersTextBoxBehavior),
         new FrameworkPropertyMetadata(".*"));
    public string RegularExpression
    {
        get
        {
            return (string)base.GetValue(RegularExpressionProperty);
        }
        set
        {
            base.SetValue(RegularExpressionProperty, value);
        }
    }

    public static readonly DependencyProperty MaxLengthProperty =
        DependencyProperty.Register("MaxLength", typeof(int), typeof(AllowableCharactersTextBoxBehavior),
        new FrameworkPropertyMetadata(int.MinValue));
    public int MaxLength
    {
        get
        {
            return (int)base.GetValue(MaxLengthProperty);
        }
        set
        {
            base.SetValue(MaxLengthProperty, value);
        }
    }

    protected override void OnAttached()
    {
        base.OnAttached();
        AssociatedObject.PreviewTextInput += OnPreviewTextInput;
        DataObject.AddPastingHandler(AssociatedObject, OnPaste);
    }

    private void OnPaste(object sender, DataObjectPastingEventArgs e)
    {
        if (e.DataObject.GetDataPresent(DataFormats.Text))
        {
            string text = Convert.ToString(e.DataObject.GetData(DataFormats.Text));

            if (!IsValid(text, true))
            {
                e.CancelCommand();
            }
        }
        else
        {
            e.CancelCommand();
        }
    }

    void OnPreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
    {
        e.Handled = !IsValid(e.Text, false);
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();
        AssociatedObject.PreviewTextInput -= OnPreviewTextInput;
        DataObject.RemovePastingHandler(AssociatedObject, OnPaste);
    }

    private bool IsValid(string newText, bool paste)
    {
        return !ExceedsMaxLength(newText, paste) && Regex.IsMatch(newText, RegularExpression);
    }

    private bool ExceedsMaxLength(string newText, bool paste)
    {
        if (MaxLength == 0) return false;

        return LengthOfModifiedText(newText, paste) > MaxLength;
    }

    private int LengthOfModifiedText(string newText, bool paste)
    {
        var countOfSelectedChars = this.AssociatedObject.SelectedText.Length;
        var caretIndex = this.AssociatedObject.CaretIndex;
        string text = this.AssociatedObject.Text;

        if (countOfSelectedChars > 0 || paste)
        {
            text = text.Remove(caretIndex, countOfSelectedChars);
            return text.Length + newText.Length;
        }
        else
        {
            var insert = Keyboard.IsKeyToggled(Key.Insert);

            return insert && caretIndex < text.Length ? text.Length : text.Length + newText.Length;
        }
    }
}

関連するビューコードは次のとおりです。

<TextBox MaxLength="50" TextWrapping="Wrap" MaxWidth="150" Margin="4"
 Text="{Binding Path=FileNameToPublish}" >
     <interactivity:Interaction.Behaviors>
         <v:AllowableCharactersTextBoxBehavior RegularExpression="^[0-9.\-]+$" MaxLength="50" />
     </interactivity:Interaction.Behaviors>
</TextBox>

1
この素晴らしいソリューションに触発されて、私はいくつかの改善を実装しました。以下のスレッドでチェックしてください。
Alex Klaus

2
こんにちは。これは少し遅れていることはわかっていますが、実装しようとしていますが、エラーが発生し続けます。いくつかの参照が不足していると思います。クラスを作成した後、デフォルト以外に入力するためのものはありますか?
提供

1
@Offerはい、xaml ウィンドウの上部にxmlns:interactivity = " schemas.microsoft.com/expression/2010/interactivity " が含まれていることを確認してください。
WiteCastle 2014年

式は廃止されました。このアプローチはクリーンですが、もう保守されていないコードを使用しています。
Robert Baker

1
したがって、IsValid関数を編集して!ExceedsMaxLength(newText、paste)&& Regex.IsMatch(String.Concat(this.AssociatedObject.Text、newText)、RegularExpression);を返す場合、次に、これは文字列全体を評価します。ところで-行動でこのオプションが大好きです!!
Rogala 2015年

59

これはWilPの回答の改善されたソリューションです。私の改善点は:

  • DelおよびBackspaceでの動作の改善ボタンの
  • 追加されました EmptyValue空の文字列が不適切な場合のプロパティの
  • いくつかの小さな誤植を修正しました
/// <summary>
///     Regular expression for Textbox with properties: 
///         <see cref="RegularExpression"/>, 
///         <see cref="MaxLength"/>,
///         <see cref="EmptyValue"/>.
/// </summary>
public class TextBoxInputRegExBehaviour : Behavior<TextBox>
{
    #region DependencyProperties
    public static readonly DependencyProperty RegularExpressionProperty =
        DependencyProperty.Register("RegularExpression", typeof(string), typeof(TextBoxInputRegExBehaviour), new FrameworkPropertyMetadata(".*"));

    public string RegularExpression
    {
        get { return (string)GetValue(RegularExpressionProperty); }
        set { SetValue(RegularExpressionProperty, value); }
    }

    public static readonly DependencyProperty MaxLengthProperty =
        DependencyProperty.Register("MaxLength", typeof(int), typeof(TextBoxInputRegExBehaviour),
                                        new FrameworkPropertyMetadata(int.MinValue));

    public int MaxLength
    {
        get { return (int)GetValue(MaxLengthProperty); }
        set { SetValue(MaxLengthProperty, value); }
    }

    public static readonly DependencyProperty EmptyValueProperty =
        DependencyProperty.Register("EmptyValue", typeof(string), typeof(TextBoxInputRegExBehaviour), null);

    public string EmptyValue
    {
        get { return (string)GetValue(EmptyValueProperty); }
        set { SetValue(EmptyValueProperty, value); }
    }
    #endregion

    /// <summary>
    ///     Attach our behaviour. Add event handlers
    /// </summary>
    protected override void OnAttached()
    {
        base.OnAttached();

        AssociatedObject.PreviewTextInput += PreviewTextInputHandler;
        AssociatedObject.PreviewKeyDown += PreviewKeyDownHandler;
        DataObject.AddPastingHandler(AssociatedObject, PastingHandler);
    }

    /// <summary>
    ///     Deattach our behaviour. remove event handlers
    /// </summary>
    protected override void OnDetaching()
    {
        base.OnDetaching();

        AssociatedObject.PreviewTextInput -= PreviewTextInputHandler;
        AssociatedObject.PreviewKeyDown -= PreviewKeyDownHandler;
        DataObject.RemovePastingHandler(AssociatedObject, PastingHandler);
    }

    #region Event handlers [PRIVATE] --------------------------------------

    void PreviewTextInputHandler(object sender, TextCompositionEventArgs e)
    {
        string text;
        if (this.AssociatedObject.Text.Length < this.AssociatedObject.CaretIndex)
            text = this.AssociatedObject.Text;
        else
        {
            //  Remaining text after removing selected text.
            string remainingTextAfterRemoveSelection;

            text = TreatSelectedText(out remainingTextAfterRemoveSelection)
                ? remainingTextAfterRemoveSelection.Insert(AssociatedObject.SelectionStart, e.Text)
                : AssociatedObject.Text.Insert(this.AssociatedObject.CaretIndex, e.Text);
        }

        e.Handled = !ValidateText(text);
    }

    /// <summary>
    ///     PreviewKeyDown event handler
    /// </summary>
    void PreviewKeyDownHandler(object sender, KeyEventArgs e)
    {
        if (string.IsNullOrEmpty(this.EmptyValue))
            return;

        string text = null;

        // Handle the Backspace key
        if (e.Key == Key.Back)
        {
            if (!this.TreatSelectedText(out text))
            {
                if (AssociatedObject.SelectionStart > 0)
                    text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart - 1, 1);
            }
        }
        // Handle the Delete key
        else if (e.Key == Key.Delete)
        {
            // If text was selected, delete it
            if (!this.TreatSelectedText(out text) && this.AssociatedObject.Text.Length > AssociatedObject.SelectionStart)
            {
                // Otherwise delete next symbol
                text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart, 1);
            }
        }

        if (text == string.Empty)
        {
            this.AssociatedObject.Text = this.EmptyValue;
            if (e.Key == Key.Back)
                AssociatedObject.SelectionStart++;
            e.Handled = true;
        }
    }

    private void PastingHandler(object sender, DataObjectPastingEventArgs e)
    {
        if (e.DataObject.GetDataPresent(DataFormats.Text))
        {
            string text = Convert.ToString(e.DataObject.GetData(DataFormats.Text));

            if (!ValidateText(text))
                e.CancelCommand();
        }
        else
            e.CancelCommand();
    }
    #endregion Event handlers [PRIVATE] -----------------------------------

    #region Auxiliary methods [PRIVATE] -----------------------------------

    /// <summary>
    ///     Validate certain text by our regular expression and text length conditions
    /// </summary>
    /// <param name="text"> Text for validation </param>
    /// <returns> True - valid, False - invalid </returns>
    private bool ValidateText(string text)
    {
        return (new Regex(this.RegularExpression, RegexOptions.IgnoreCase)).IsMatch(text) && (MaxLength == int.MinValue || text.Length <= MaxLength);
    }

    /// <summary>
    ///     Handle text selection
    /// </summary>
    /// <returns>true if the character was successfully removed; otherwise, false. </returns>
    private bool TreatSelectedText(out string text)
    {
        text = null;
        if (AssociatedObject.SelectionLength <= 0) 
            return false;

        var length = this.AssociatedObject.Text.Length;
        if (AssociatedObject.SelectionStart >= length)
            return true;

        if (AssociatedObject.SelectionStart + AssociatedObject.SelectionLength >= length)
            AssociatedObject.SelectionLength = length - AssociatedObject.SelectionStart;

        text = this.AssociatedObject.Text.Remove(AssociatedObject.SelectionStart, AssociatedObject.SelectionLength);
        return true;
    }
    #endregion Auxiliary methods [PRIVATE] --------------------------------
}

使い方はかなり簡単です:

<i:Interaction.Behaviors>
    <behaviours:TextBoxInputRegExBehaviour RegularExpression="^\d+$" MaxLength="9" EmptyValue="0" />
</i:Interaction.Behaviors>

1
このソリューションはかなり優れています。しかし、あなたは小さなミスを犯しました:設定しない場合はMaxLength、あなたのconditonの(this.MaxLength == 0 || text.Length <= this.MaxLength)常にリターンをfalse新しいテキストをテストするとき。のデフォルト値として設定する(this.MaxLength == int.MinValue || text.Length <= this.MaxLength)ので、これはより良いはずint.MinValueですMaxLength
ChristophMeißner2017

1
@Christophありがとうございます、はい、あなたは正しいです。回答を変更しました。
Alex Klaus

@AlexKlaus UpdateSourceTrigger=PropertyChangedバインディングに追加するまで、これはうまく機能します。UpdateSourceTrigger設定を変更したときにこのコードを機能させる方法はありPropertyChangedますか?このコードを共有していただきありがとうございます。
ジュニア

32

これは、MVVMを使用してこれを行う非常にシンプルで簡単な方法です。

textBoxをビューモデルの整数プロパティにバインドすると、gemのように動作します...テキストボックスに整数以外の値が入力された場合でも検証が表示されます。

XAMLコード:

<TextBox x:Name="contactNoTxtBox"  Text="{Binding contactNo}" />

モデルコードを表示:

private long _contactNo;
public long contactNo
{
    get { return _contactNo; }
    set
    {
        if (value == _contactNo)
            return;
        _contactNo = value;
        OnPropertyChanged();
    }
}

しかし、質問には「数字と小数点を受け入れることを望んでいる」が含まれていました。この回答で小数点は受け入れられますか?
Peter Mortensen、

に変更longしてみましたがfloat、すぐに検証しても機能しませんでした。UpdateSourceTrigger="PropertyChanged"バインディングに追加したので、各文字が入力されたときに検証が実行され、「。」を入力できなくなりました。不正な文字が存在しない限り、TextBox内(「1x.234」と入力してから「x」を削除する必要がありました)。また、このモードでは少し鈍感になります。これSystem.Number.ParseSingle()は作業に使用するように見えるため、さまざまな表記を受け入れます。
fadden

@wolleは検証がどのように機能するかを説明しないため、おそらく投票されません。
ポールマッカーシー、

26

VALIDATION RULEを追加して、テキストが変更されたときにデータが数値であるかどうかを確認し、数値である場合は処理を続行できるようにします。そうでない場合は、そのフィールドでは数値データのみが受け入れられることをユーザーに確認します。

Windows Presentation Foundationの検証で詳細を読む


6
これは、SO標準に対する実際の答えではありません。
Robert Baker

これは.netの方法のようです。
Telemat

1
ある正しい答え:検証はvieneモデルまたはモデルレベルでなければなりません。さらに、次のような数値型にバインドdoubleするだけで、標準の検証が既に提供されています。

24

Extented WPFツールキットには、NumericUpDownがあります。 ここに画像の説明を入力してください


私はこのコントロールを試しましたが、UpdateSourceTrigger = PropertyChangedでスピナーを使用すると問題が発生し、一般にユーザーが科学表記を入力するのが困難です。
Menno Deij-ファンレイスウェイク2013年

5
NumericUpDown現在は廃止されていることに注意してください。DecimalUpDown更新されたツールキットExtended WPF Toolkit™Community Edition
itho

20

検証ルールを実装してTextBoxに適用することもできます。

  <TextBox>
    <TextBox.Text>
      <Binding Path="OnyDigitInput" Mode="TwoWay" UpdateSourceTrigger="PropertyChanged">
        <Binding.ValidationRules>
          <conv:OnlyDigitsValidationRule />
        </Binding.ValidationRules>
      </Binding>
    </TextBox.Text>

次のようにルールを実装すると(他の回答で提案されているのと同じ正規表現を使用):

public class OnlyDigitsValidationRule : ValidationRule
{
    public override ValidationResult Validate(object value, CultureInfo cultureInfo)
    {
        var validationResult = new ValidationResult(true, null);

        if(value != null)
        {
            if (!string.IsNullOrEmpty(value.ToString()))
            {
                var regex = new Regex("[^0-9.-]+"); //regex that matches disallowed text
                var parsingOk = !regex.IsMatch(value.ToString());
                if (!parsingOk)
                {
                    validationResult = new ValidationResult(false, "Illegal Characters, Please Enter Numeric Value");
                }
            }
        }

        return validationResult;
    }
}

10進数を入力する場合は、テキストが「。」で終わるときに「有効」を返さないでください。stackoverflow.com/a/27838893/417939を
YantingChen

14

ここに私はレイの答えに触発された簡単な解決策があります。これは、任意の形式の番号を識別するのに十分なはずです。

このソリューションは、正の数、整数値、または小数点以下の最大数まで正確な値のみが必要な場合にも簡単に変更できます。


Rayの回答で提案されているように、まずPreviewTextInputイベントを追加する必要があります。

<TextBox PreviewTextInput="TextBox_OnPreviewTextInput"/>

次に、次のコードを後ろに配置します。

private void TextBox_OnPreviewTextInput(object sender, TextCompositionEventArgs e)
{
    var textBox = sender as TextBox;
    // Use SelectionStart property to find the caret position.
    // Insert the previewed text into the existing text in the textbox.
    var fullText = textBox.Text.Insert(textBox.SelectionStart, e.Text);

    double val;
    // If parsing is successful, set Handled to false
    e.Handled = !double.TryParse(fullText, out val);
}

4
私はこの答えがたくさん好きです、シンプルで効果的です+
Pulle

神とシンプルですが、醜いのでスペースが許されます
Momo

2
これにより、テキストボックスに文字列を貼り付けることができます
FCin

8

テンキーの数字とバックスペースを許可しました:

    private void TextBox_PreviewKeyDown(object sender, KeyEventArgs e)
    {
        int key = (int)e.Key;

        e.Handled = !(key >= 34 && key <= 43 || 
                      key >= 74 && key <= 83 || 
                      key == 2);
    }

8
マジックナンバーの代わりに列挙値を使用することをお勧めします:var keyEnum = (System.Windows.Input.Key) e.Key; e.Handled = !(keyEnum >= System.Windows.Input.Key.D0 && keyEnum <= System.Windows.Input.Key.D9 || keyEnum >= System.Windows.Input.Key.NumPad0 && keyEnum <= System.Windows.Input.Key.NumPad9 || keyEnum == System.Windows.Input.Key.Back);
itho

7

私はそれを仮定します:

  1. 数値入力のみを許可するTextBoxのTextプロパティは、最初は有効な数値(2.7172など)に設定されています。

  2. あなたのテキストボックスはメインウィンドウの子です

  3. あなたのメインウィンドウはクラスWindow1です

  4. あなたのTextBox名はnumericTBです

基本的な考え方:

  1. 追加: private string previousText;メインウィンドウクラス(Window1)に

  2. 追加: previousText = numericTB.Text;メインウィンドウコンストラクターに

  3. 次のように、numericTB.TextChangedイベントのハンドラーを作成します。

    private void numericTB_TextChanged(object sender, TextChangedEventArgs e)
    {
        double num = 0;
        bool success = double.TryParse(((TextBox)sender).Text, out num);
        if (success & num >= 0)
            previousText = ((TextBox)sender).Text;
        else
            ((TextBox)sender).Text = previousText;
    }

これにより、previousTextが有効である限りそれをnumericTB.Textに設定し続け、ユーザーが気に入らないものをユーザーが書き込んだ場合は、numericTB.Textを最後の有効な値に設定します。もちろん、これは単なる基本的な考え方であり、単なる「ばか耐性」ではなく、「ばか証拠」ではありません。たとえば、ユーザーがスペースをいじるケースは処理しません。だからここに私が「ばか証明」だと思う完全な解決策があります、そして私が間違っているなら教えてください:

  1. Window1.xamlファイルの内容:

    <Window x:Class="IdiotProofNumericTextBox.Window1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="Window1" Height="300" Width="300">
        <Grid>
            <TextBox Height="30" Width="100" Name="numericTB" TextChanged="numericTB_TextChanged"/>
        </Grid>
    </Window>
  2. Window.xaml.csファイルの内容:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Windows;
    using System.Windows.Controls;
    using System.Windows.Data;
    using System.Windows.Documents;
    using System.Windows.Input;
    using System.Windows.Media;
    using System.Windows.Media.Imaging;
    using System.Windows.Navigation;
    using System.Windows.Shapes;
    
    namespace IdiotProofNumericTextBox
    {
        public partial class Window1 : Window
        {
            private string previousText;
    
            public Window1()
            {
                InitializeComponent();
                previousText = numericTB.Text;
            }
    
            private void numericTB_TextChanged(object sender, TextChangedEventArgs e)
            {
                if (string.IsNullOrEmpty(((TextBox)sender).Text))
                    previousText = "";
                else
                {
                    double num = 0;
                    bool success = double.TryParse(((TextBox)sender).Text, out num);
                    if (success & num >= 0)
                    {
                        ((TextBox)sender).Text.Trim();
                        previousText = ((TextBox)sender).Text;
                    }
                    else
                    {
                        ((TextBox)sender).Text = previousText;
                        ((TextBox)sender).SelectionStart = ((TextBox)sender).Text.Length;
                    }
                }
            }
        }
    }

以上です。多くのTextBoxがある場合は、TextBoxから継承するCustomControlを作成して、previousTextとnumericTB_TextChangedを別のファイルにラップできるようにすることをお勧めします。


すごい!どうすれば前に負の記号を付けることができますか?
theNoobGuy 2011

6

これが必要な唯一のコードです:

void MyTextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    e.Handled = new Regex("[^0-9]+").IsMatch(e.Text);
}

これにより、テキストボックスへの数値の入力のみが可能になります。

小数点またはマイナス記号を許可するには、正規表現をに変更し[^0-9.-]+ます。


1
1つのマイナーなnitpickを除いて非常に良い解決策:空白がPreviewTextInputイベントをトリガーしないため、空白を入力することを妨げません。
Tim Pohlmann、2016

バックスペースもそれを起動しません。
Winger Sendon

6

基本的な機能を実行するために多くのコードを記述したくない場合(なぜ人々が長いメソッドを作成するのか分かりません)、次のようにすることができます。

  1. 名前空間を追加:

    using System.Text.RegularExpressions;
  2. XAMLで、TextChangedプロパティを設定します。

    <TextBox x:Name="txt1" TextChanged="txt1_TextChanged"/>
  3. WPFのtxt1_TextChangedメソッドの下に、次を追加しRegex.Replaceます。

    private void txt1_TextChanged(object sender, TextChangedEventArgs e)
    {
        txt1.Text = Regex.Replace(txt1.Text, "[^0-9]+", "");
    }

2
BehaviorまたはAttachedPropertyを使用する方がずっとクリーンです。すべてのビュー/すべてのテキストボックスでコードビハインドをいじる必要はありません
ルフォ卿

うまくいく
Momo

6

別のアプローチは、添付されたビヘイビアーを使用することです。プロジェクト全体のテキストボックスで使用できるカスタムTextBoxHelperクラスを実装しました。私は、この目的のためにすべてのテキストボックスとすべての個別のXAMLファイルのイベントをサブスクライブすると時間がかかることがあると考えました。

私が実装したTextBoxHelperクラスには、次の機能があります。

  • DoubleIntUintNatural形式の数値のみのフィルタリングと受け入れ
  • フィルタリングと受け入れるだけでもまたは奇数の番号
  • 貼り付けイベントハンドラー処理して、無効なテキストを数値テキストボックスに貼り付けないようにする
  • テキストボックスのTextChangedイベントにサブスクライブすることにより、最後のショットとして無効なデータを防止するために使用されるデフォルト値を設定できます

TextBoxHelperクラスの実装は次のとおりです。

public static class TextBoxHelper
{
    #region Enum Declarations

    public enum NumericFormat
    {
        Double,
        Int,
        Uint,
        Natural
    }

    public enum EvenOddConstraint
    {
        All,
        OnlyEven,
        OnlyOdd
    }

    #endregion

    #region Dependency Properties & CLR Wrappers

    public static readonly DependencyProperty OnlyNumericProperty =
        DependencyProperty.RegisterAttached("OnlyNumeric", typeof(NumericFormat?), typeof(TextBoxHelper),
            new PropertyMetadata(null, DependencyPropertiesChanged));
    public static void SetOnlyNumeric(TextBox element, NumericFormat value) =>
        element.SetValue(OnlyNumericProperty, value);
    public static NumericFormat GetOnlyNumeric(TextBox element) =>
        (NumericFormat) element.GetValue(OnlyNumericProperty);


    public static readonly DependencyProperty DefaultValueProperty =
        DependencyProperty.RegisterAttached("DefaultValue", typeof(string), typeof(TextBoxHelper),
            new PropertyMetadata(null, DependencyPropertiesChanged));
    public static void SetDefaultValue(TextBox element, string value) =>
        element.SetValue(DefaultValueProperty, value);
    public static string GetDefaultValue(TextBox element) => (string) element.GetValue(DefaultValueProperty);


    public static readonly DependencyProperty EvenOddConstraintProperty =
        DependencyProperty.RegisterAttached("EvenOddConstraint", typeof(EvenOddConstraint), typeof(TextBoxHelper),
            new PropertyMetadata(EvenOddConstraint.All, DependencyPropertiesChanged));
    public static void SetEvenOddConstraint(TextBox element, EvenOddConstraint value) =>
        element.SetValue(EvenOddConstraintProperty, value);
    public static EvenOddConstraint GetEvenOddConstraint(TextBox element) =>
        (EvenOddConstraint)element.GetValue(EvenOddConstraintProperty);

    #endregion

    #region Dependency Properties Methods

    private static void DependencyPropertiesChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
    {
        if (!(d is TextBox textBox))
            throw new Exception("Attached property must be used with TextBox.");

        switch (e.Property.Name)
        {
            case "OnlyNumeric":
            {
                var castedValue = (NumericFormat?) e.NewValue;

                if (castedValue.HasValue)
                {
                    textBox.PreviewTextInput += TextBox_PreviewTextInput;
                    DataObject.AddPastingHandler(textBox, TextBox_PasteEventHandler);
                }
                else
                {
                    textBox.PreviewTextInput -= TextBox_PreviewTextInput;
                    DataObject.RemovePastingHandler(textBox, TextBox_PasteEventHandler);
                }

                break;
            }

            case "DefaultValue":
            {
                var castedValue = (string) e.NewValue;

                if (castedValue != null)
                {
                    textBox.TextChanged += TextBox_TextChanged;
                }
                else
                {
                    textBox.TextChanged -= TextBox_TextChanged;
                }

                break;
            }
        }
    }

    #endregion

    private static void TextBox_PreviewTextInput(object sender, TextCompositionEventArgs e)
    {
        var textBox = (TextBox)sender;

        string newText;

        if (textBox.SelectionLength == 0)
        {
            newText = textBox.Text.Insert(textBox.SelectionStart, e.Text);
        }
        else
        {
            var textAfterDelete = textBox.Text.Remove(textBox.SelectionStart, textBox.SelectionLength);

            newText = textAfterDelete.Insert(textBox.SelectionStart, e.Text);
        }

        var evenOddConstraint = GetEvenOddConstraint(textBox);

        switch (GetOnlyNumeric(textBox))
        {
            case NumericFormat.Double:
            {
                if (double.TryParse(newText, out double number))
                {
                    switch (evenOddConstraint)
                    {
                        case EvenOddConstraint.OnlyEven:

                            if (number % 2 != 0)
                                e.Handled = true;
                            else
                                e.Handled = false;

                            break;

                        case EvenOddConstraint.OnlyOdd:

                            if (number % 2 == 0)
                                e.Handled = true;
                            else
                                e.Handled = false;

                            break;
                    }
                }
                else
                    e.Handled = true;

                break;
            }

            case NumericFormat.Int:
            {
                if (int.TryParse(newText, out int number))
                {
                    switch (evenOddConstraint)
                    {
                        case EvenOddConstraint.OnlyEven:

                            if (number % 2 != 0)
                                e.Handled = true;
                            else
                                e.Handled = false;

                            break;

                        case EvenOddConstraint.OnlyOdd:

                            if (number % 2 == 0)
                                e.Handled = true;
                            else
                                e.Handled = false;

                            break;
                    }
                }
                else
                    e.Handled = true;

                break;
            }

            case NumericFormat.Uint:
            {
                if (uint.TryParse(newText, out uint number))
                {
                    switch (evenOddConstraint)
                    {
                        case EvenOddConstraint.OnlyEven:

                            if (number % 2 != 0)
                                e.Handled = true;
                            else
                                e.Handled = false;

                            break;

                        case EvenOddConstraint.OnlyOdd:

                            if (number % 2 == 0)
                                e.Handled = true;
                            else
                                e.Handled = false;

                            break;
                    }
                }
                else
                    e.Handled = true;

                break;
            }

            case NumericFormat.Natural:
            {
                if (uint.TryParse(newText, out uint number))
                {
                    if (number == 0)
                        e.Handled = true;
                    else
                    {
                        switch (evenOddConstraint)
                        {
                            case EvenOddConstraint.OnlyEven:

                                if (number % 2 != 0)
                                    e.Handled = true;
                                else
                                    e.Handled = false;

                                break;

                            case EvenOddConstraint.OnlyOdd:

                                if (number % 2 == 0)
                                    e.Handled = true;
                                else
                                    e.Handled = false;

                                break;
                        }
                    }
                }
                else
                    e.Handled = true;

                break;
            }
        }
    }

    private static void TextBox_PasteEventHandler(object sender, DataObjectPastingEventArgs e)
    {
        var textBox = (TextBox)sender;

        if (e.DataObject.GetDataPresent(typeof(string)))
        {
            var clipboardText = (string) e.DataObject.GetData(typeof(string));

            var newText = textBox.Text.Insert(textBox.SelectionStart, clipboardText);

            var evenOddConstraint = GetEvenOddConstraint(textBox);

            switch (GetOnlyNumeric(textBox))
            {
                case NumericFormat.Double:
                {
                    if (double.TryParse(newText, out double number))
                    {
                        switch (evenOddConstraint)
                        {
                            case EvenOddConstraint.OnlyEven:

                                if (number % 2 != 0)
                                    e.CancelCommand();

                                break;

                            case EvenOddConstraint.OnlyOdd:

                                if (number % 2 == 0)
                                    e.CancelCommand();

                                break;
                        }
                    }
                    else
                        e.CancelCommand();

                    break;
                }

                case NumericFormat.Int:
                {
                    if (int.TryParse(newText, out int number))
                    {
                        switch (evenOddConstraint)
                        {
                            case EvenOddConstraint.OnlyEven:

                                if (number % 2 != 0)
                                    e.CancelCommand();

                                break;

                            case EvenOddConstraint.OnlyOdd:

                                if (number % 2 == 0)
                                    e.CancelCommand();


                                break;
                        }
                    }
                    else
                        e.CancelCommand();

                    break;
                }

                case NumericFormat.Uint:
                {
                    if (uint.TryParse(newText, out uint number))
                    {
                        switch (evenOddConstraint)
                        {
                            case EvenOddConstraint.OnlyEven:

                                if (number % 2 != 0)
                                    e.CancelCommand();

                                break;

                            case EvenOddConstraint.OnlyOdd:

                                if (number % 2 == 0)
                                    e.CancelCommand();


                                break;
                        }
                    }
                    else
                        e.CancelCommand();

                    break;
                }

                case NumericFormat.Natural:
                {
                    if (uint.TryParse(newText, out uint number))
                    {
                        if (number == 0)
                            e.CancelCommand();
                        else
                        {
                            switch (evenOddConstraint)
                            {
                                case EvenOddConstraint.OnlyEven:

                                    if (number % 2 != 0)
                                        e.CancelCommand();

                                    break;

                                case EvenOddConstraint.OnlyOdd:

                                    if (number % 2 == 0)
                                        e.CancelCommand();

                                    break;
                            }
                        }
                    }
                    else
                    {
                        e.CancelCommand();
                    }

                    break;
                }
            }
        }
        else
        {
            e.CancelCommand();
        }
    }

    private static void TextBox_TextChanged(object sender, TextChangedEventArgs e)
    {
        var textBox = (TextBox)sender;

        var defaultValue = GetDefaultValue(textBox);

        var evenOddConstraint = GetEvenOddConstraint(textBox);

        switch (GetOnlyNumeric(textBox))
        {
            case NumericFormat.Double:
            {
                if (double.TryParse(textBox.Text, out double number))
                {
                    switch (evenOddConstraint)
                    {
                        case EvenOddConstraint.OnlyEven:

                            if (number % 2 != 0)
                                textBox.Text = defaultValue;

                            break;

                        case EvenOddConstraint.OnlyOdd:

                            if (number % 2 == 0)
                                textBox.Text = defaultValue;

                            break;
                    }
                }
                else
                    textBox.Text = defaultValue;

                break;
            }

            case NumericFormat.Int:
            {
                if (int.TryParse(textBox.Text, out int number))
                {
                    switch (evenOddConstraint)
                    {
                        case EvenOddConstraint.OnlyEven:

                            if (number % 2 != 0)
                                textBox.Text = defaultValue;

                            break;

                        case EvenOddConstraint.OnlyOdd:

                            if (number % 2 == 0)
                                textBox.Text = defaultValue;

                            break;
                    }
                }
                else
                    textBox.Text = defaultValue;

                break;
            }

            case NumericFormat.Uint:
            {
                if (uint.TryParse(textBox.Text, out uint number))
                {
                    switch (evenOddConstraint)
                    {
                        case EvenOddConstraint.OnlyEven:

                            if (number % 2 != 0)
                                textBox.Text = defaultValue;

                            break;

                        case EvenOddConstraint.OnlyOdd:

                            if (number % 2 == 0)
                                textBox.Text = defaultValue;

                            break;
                    }
                }
                else
                    textBox.Text = defaultValue;

                break;
            }

            case NumericFormat.Natural:
            {
                if (uint.TryParse(textBox.Text, out uint number))
                {
                    if(number == 0)
                        textBox.Text = defaultValue;
                    else
                    {
                        switch (evenOddConstraint)
                        {
                            case EvenOddConstraint.OnlyEven:

                                if (number % 2 != 0)
                                    textBox.Text = defaultValue;

                                break;

                            case EvenOddConstraint.OnlyOdd:

                                if (number % 2 == 0)
                                    textBox.Text = defaultValue;

                                break;
                        }
                    }
                }
                else
                {
                    textBox.Text = defaultValue;
                }

                break;
            }
        }
    }
}

そして、これはその簡単な使用法のいくつかの例です:

<TextBox viewHelpers:TextBoxHelper.OnlyNumeric="Double"
         viewHelpers:TextBoxHelper.DefaultValue="1"/>

または

<TextBox viewHelpers:TextBoxHelper.OnlyNumeric="Natural"
         viewHelpers:TextBoxHelper.DefaultValue="3"
         viewHelpers:TextBoxHelper.EvenOddConstraint="OnlyOdd"/>

TextBoxHelperはviewHelpers xmlnsエイリアスにあることに注意してください

この実装が他の人の仕事を楽にすることを願っています:)


1
これは、DataTemplate内でテキストボックスを使用する場合に最適です。
NucS 2018年

@NucSどういたしまして、親愛なるNucS
Amir Mahdi Nassiri、

3
すばらしい答えですが、あなたの方法は読みにくいと思います。おそらく、それらをより小さなものに分解する必要があります。あなたにとって、メソッドの理想的な長さは何ですか?を
アンソニー

建設的なフィードバックをありがとう@Anthony
Amir Mahdi Nassiri

4
e.Handled = (int)e.Key >= 43 || (int)e.Key <= 34;

テキストボックスのプレビューキーダウンイベント。


3
ただし、バックスペースは許可されません。
sventevit 2012

2
バックスペースは2、タブは3
Daniel

6
私の経験では、他の一部のコメンターが指摘しているように、この種のスマートトリックは最終的にはお尻を噛みます。
DonkeyMaster 2014

左矢印右矢印25で、23である
アーロン

4
PreviewTextInput += (s, e) =>
{
    e.Handled = !e.Text.All(char.IsDigit);
};

2
これはまた、ドット受け入れない.ため、e.Text最後の入力文字を返し、ドットが失敗しますIsDigitチェックを。
Anthony、

4

XAMLファイルで整数と10進数のみを使用してこのタイプの問題をすばやく簡単に実装する方法を探している場合は、PreviewTextInputプロパティをに追加してからTextBox、xaml.csファイルで次のように使用します。

private void Text_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    e.Handled = !char.IsDigit(e.Text.Last()) && !e.Text.Last() == '.';
}

他の人が言及しているように、科学表記法で何かをしている場合を除いて、毎回文字列全体をチェックし続けることは一種の冗長です(ただし、 'e'のような特定の文字を追加する場合、記号/文字を追加する単純な正規表現は本当にシンプルで他の回答に示されています)。ただし、単純な浮動小数点値の場合は、このソリューションで十分です。

ラムダ式のワンライナーとして書かれています:

private void Text_PreviewTextInput(object sender, TextCompositionEventArgs e) => e.Handled = !char.IsDigit(e.Text.Last() && !e.Text.Last() == '.');

3

テキストボックス変更イベントの検証を行うことができます。次の実装は、数値と小数点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;     
} 

それは私にはうまく
いき

3

これはどう?私にはうまくいきます。エッジケースを見逃さなかったことを願っています...

MyTextBox.PreviewTextInput += (sender, args) =>
{
    if (!int.TryParse(args.Text, out _))
    {
        args.Handled = true;
    }
};

DataObject.AddPastingHandler(MyTextBox, (sender, args) =>
{
    var isUnicodeText = args.SourceDataObject.GetDataPresent(DataFormats.UnicodeText, true);
    if (!isUnicodeText)
    {
        args.CancelCommand();
    }

    var data = args.SourceDataObject.GetData(DataFormats.UnicodeText) as string;
    if (!int.TryParse(data, out _))
    {
        args.CancelCommand();
    }
});

この作品はありがとう
Aljohn Yamaro

2

Windowsフォームでは簡単でした。KeyPressのイベントを追加でき、すべてが簡単に機能します。ただし、WPFではそのイベントはありません。しかし、もっと簡単な方法があります。

WPF TextBoxには、すべてに共通のTextChangedイベントがあります。これには、貼り付け、タイピングなど、頭に浮かぶ可能性のあるあらゆるものが含まれます。

だからあなたはこのようなことをすることができます:

XAML:

<TextBox name="txtBox1" ... TextChanged="TextBox_TextChanged"/>

後ろのコード:

private void TextBox_TextChanged(object sender, TextChangedEventArgs e) {
    string s = Regex.Replace(((TextBox)sender).Text, @"[^\d.]", "");
    ((TextBox)sender).Text = s;
}

これも受け入れ.ます。必要ない場合は、regexステートメントから削除してください@[^\d]

:このイベントは、senderオブジェクトのテキストを使用するため、多くのTextBoxで使用できます。イベントは1回だけ記述し、複数のTextBoxに使用できます。


2

今私はこの質問が受け入れられた答えを持っていることを知っています個人的には少し混乱しているので、それよりも簡単なはずです。だから私はそれが私ができる限りうまく機能するようにした方法を示すようにしようとします:

では、Windowsフォーム、というイベントがありますKeyPressタスクのこの種のために完璧に良いです。しかし、それはWPFには存在しないため、代わりにPreviewTextInputイベントを使用します。また、検証については、a foreachを使用してループし、textbox.Textそれが条件と一致するかどうかを確認できると信じていますが、正直なところ、これが正規表現の目的です。

聖なるコードに飛び込む前にもう一つ。イベントを発生させるには、2つのことを実行できます。

  1. XAMLを使用して、呼び出す関数をプログラムに指示します。 <PreviewTextInput="textBox_PreviewTextInput/>
  2. Loaded(textBoxが入っている)フォームのイベントで実行します。 textBox.PreviewTextInput += onlyNumeric;

私はこのような状況で、あなたはほとんど同じ条件(適用するために必要とされますので、第二の方法が優れていると思うregex以上のものに)をTextBoxし、あなた自身を繰り返したくはありません!

最後に、次のようにします。

private void onlyNumeric(object sender, TextCompositionEventArgs e)
{
    string onlyNumeric = @"^([0-9]+(.[0-9]+)?)$";
    Regex regex = new Regex(onlyNumeric);
    e.Handled = !regex.IsMatch(e.Text);
}

2

これが私のバージョンです。これValidatingTextBoxは、「有効」でない場合に行われた処理を元に戻すだけの基本クラスに基づいています。貼り付け、切り取り、削除、バックスペース、+、-などをサポートしています。

32ビット整数の場合、intと比較するだけのInt32TextBoxクラスがあります。浮動小数点検証クラスも追加しました。

public class ValidatingTextBox : TextBox
{
    private bool _inEvents;
    private string _textBefore;
    private int _selectionStart;
    private int _selectionLength;

    public event EventHandler<ValidateTextEventArgs> ValidateText;

    protected override void OnPreviewKeyDown(KeyEventArgs e)
    {
        if (_inEvents)
            return;

        _selectionStart = SelectionStart;
        _selectionLength = SelectionLength;
        _textBefore = Text;
    }

    protected override void OnTextChanged(TextChangedEventArgs e)
    {
        if (_inEvents)
            return;

        _inEvents = true;
        var ev = new ValidateTextEventArgs(Text);
        OnValidateText(this, ev);
        if (ev.Cancel)
        {
            Text = _textBefore;
            SelectionStart = _selectionStart;
            SelectionLength = _selectionLength;
        }
        _inEvents = false;
    }

    protected virtual void OnValidateText(object sender, ValidateTextEventArgs e) => ValidateText?.Invoke(this, e);
}

public class ValidateTextEventArgs : CancelEventArgs
{
    public ValidateTextEventArgs(string text) => Text = text;

    public string Text { get; }
}

public class Int32TextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !int.TryParse(e.Text, out var value);
}

public class Int64TextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !long.TryParse(e.Text, out var value);
}

public class DoubleTextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !double.TryParse(e.Text, out var value);
}

public class SingleTextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !float.TryParse(e.Text, out var value);
}

public class DecimalTextBox : ValidatingTextBox
{
    protected override void OnValidateText(object sender, ValidateTextEventArgs e) => e.Cancel = !decimal.TryParse(e.Text, out var value);
}

注1:WPFバインディングを使用する場合は、バインドされたプロパティタイプに適合するクラスを使用する必要があります。そうしないと、奇妙な結果が生じる可能性があります。

注2:WPFバインディングで浮動小数点クラスを使用する場合は、バインディングが現在のカルチャを使用して、使用したTryParseメソッドと一致することを確認してください。



1

使用する:

Private Sub DetailTextBox_PreviewTextInput( _
  ByVal sender As Object, _
  ByVal e As System.Windows.Input.TextCompositionEventArgs) _
  Handles DetailTextBox.PreviewTextInput

    If _IsANumber Then
        If Not Char.IsNumber(e.Text) Then
            e.Handled = True
        End If
    End If
End Sub

説明が正しいでしょう。
Peter Mortensen、

1

自分が取り組んでいる単純なプロジェクトのバインドされていないボックスを使用していたため、標準のバインド方法を使用できませんでした。その結果、私は既存のTextBoxコントロールを拡張するだけで他の人が非常に便利な簡単なハックを作成しました。

namespace MyApplication.InterfaceSupport
{
    public class NumericTextBox : TextBox
    {


        public NumericTextBox() : base()
        {
            TextChanged += OnTextChanged;
        }


        public void OnTextChanged(object sender, TextChangedEventArgs changed)
        {
            if (!String.IsNullOrWhiteSpace(Text))
            {
                try
                {
                    int value = Convert.ToInt32(Text);
                }
                catch (Exception e)
                {
                    MessageBox.Show(String.Format("{0} only accepts numeric input.", Name));
                    Text = "";
                }
            }
        }


        public int? Value
        {
            set
            {
                if (value != null)
                {
                    this.Text = value.ToString();
                }
                else 
                    Text = "";
            }
            get
            {
                try
                {
                    return Convert.ToInt32(this.Text);
                }
                catch (Exception ef)
                {
                    // Not numeric.
                }
                return null;
            }
        }
    }
}

明らかに、浮動小数点型の場合は、それを浮動小数点数として解析する必要があります。同じ原則が適用されます。

次に、XAMLファイルに関連する名前空間を含める必要があります。

<UserControl x:Class="MyApplication.UserControls.UnParameterisedControl"
             [ Snip ]
             xmlns:interfaceSupport="clr-namespace:MyApplication.InterfaceSupport"
             >

その後、それを通常のコントロールとして使用できます。

<interfaceSupport:NumericTextBox Height="23" HorizontalAlignment="Left" Margin="168,51,0,0" x:Name="NumericBox" VerticalAlignment="Top" Width="120" >

1

ここでいくつかのソリューションをしばらく使用した後、自分のMVVMセットアップでうまく機能する独自のソリューションを開発しました。ユーザーが誤った文字を入力できるという意味では、他の文字ほど動的ではありませんが、ボタンを押して何かを実行することをブロックします。これは、アクションを実行できないときにボタンをグレー表示するという私のテーマとうまく調和しています。

TextBoxユーザーが印刷するドキュメントのページ数を入力する必要があることを私は持っています:

<TextBox Text="{Binding NumberPagesToPrint, UpdateSourceTrigger=PropertyChanged}"/>

...このバインディングプロパティを使用:

private string _numberPagesToPrint;
public string NumberPagesToPrint
{
    get { return _numberPagesToPrint; }
    set
    {
        if (_numberPagesToPrint == value)
        {
            return;
        }

        _numberPagesToPrint = value;
        OnPropertyChanged("NumberPagesToPrint");
    }
}

私もボタンがあります:

<Button Template="{DynamicResource CustomButton_Flat}" Content="Set"
        Command="{Binding SetNumberPagesCommand}"/>

...このコマンドをバインドすると:

private RelayCommand _setNumberPagesCommand;
public ICommand SetNumberPagesCommand
{
    get
    {
        if (_setNumberPagesCommand == null)
        {
            int num;
            _setNumberPagesCommand = new RelayCommand(param => SetNumberOfPages(),
                () => Int32.TryParse(NumberPagesToPrint, out num));
        }

        return _setNumberPagesCommand;
    }
}

そしての方法がSetNumberOfPages()ありますが、このトピックでは重要ではありません。ビューの分離コードファイルにコードを追加する必要がなく、Commandプロパティを使用して動作を制御できるため、私の場合はうまくいきます。



1

WPFアプリケーションでは、TextChangedイベントを処理することでこれを処理できます。

void arsDigitTextBox_TextChanged(object sender, System.Windows.Controls.TextChangedEventArgs e)
{
    Regex regex = new Regex("[^0-9]+");
    bool handle = regex.IsMatch(this.Text);
    if (handle)
    {
        StringBuilder dd = new StringBuilder();
        int i = -1;
        int cursor = -1;
        foreach (char item in this.Text)
        {
            i++;
            if (char.IsDigit(item))
                dd.Append(item);
            else if(cursor == -1)
                cursor = i;
        }
        this.Text = dd.ToString();

        if (i == -1)
            this.SelectionStart = this.Text.Length;
        else
            this.SelectionStart = cursor;
    }
}

1

テキストフィールドにソケットポートなどの符号なしの番号のみを受け入れるようにしたい開発者向け:

WPF

<TextBox PreviewTextInput="Port_PreviewTextInput" MaxLines="1"/>

C#

private void Port_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
    e.Handled = !int.TryParse(e.Text, out int x);
}

2
このメソッドをソケットポートフィールドで本当に使用したい場合は注意してください。整数がより小さいか等しいかどうかを確認する必要があり65535ます。大きい場合は、有効なポートではありません。また、を設定するTextBox.MaxLength、プログラムまたはXAMLで5役立ちます
ビヨンド

0

これは、数字と小数点を受け入れるWPFテキストボックスを取得するために使用するものです。

class numericTextBox : TextBox
{
    protected override void OnKeyDown(KeyEventArgs e)
    {
        bool b = false;
        switch (e.Key)
        {
            case Key.Back: b = true; break;
            case Key.D0: b = true; break;
            case Key.D1: b = true; break;
            case Key.D2: b = true; break;
            case Key.D3: b = true; break;
            case Key.D4: b = true; break;
            case Key.D5: b = true; break;
            case Key.D6: b = true; break;
            case Key.D7: b = true; break;
            case Key.D8: b = true; break;
            case Key.D9: b = true; break;
            case Key.OemPeriod: b = true; break;
        }
        if (b == false)
        {
            e.Handled = true;
        }
        base.OnKeyDown(e);
    }
}

コードを新しいクラスファイルに追加し、

using System.Windows.Controls;
using System.Windows.Input;

ファイルの上部にあり、ソリューションをビルドします。その後、numericTextBoxコントロールがツールボックスの上部に表示されます。


1
NumberValidationTextBoxと正規表現を使用した以前のはるかに簡単なソリューションを参照してください。ばかげてる。
Scott Shaw-Smith、

@ ScottShaw-Smith多分受け入れられた解決策はより少ないコードですが、これより速くはありません。正規表現を使用するのではなく、多くの処理能力を必要とするプロジェクトが常にあります。
Beyondo
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.