मुझे केवल WPF में संख्यात्मक इनपुट को स्वीकार करने के लिए एक टेक्स्टबॉक्स कैसे मिलता है?


334

मैं अंकों और दशमलव बिंदु को स्वीकार करना चाह रहा हूं, लेकिन कोई संकेत नहीं।

मैंने Windows प्रपत्र के लिए NumericUpDown नियंत्रण और Microsoft से NumericUpDown कस्टम नियंत्रण के इस नमूने का उपयोग करके नमूनों को देखा है । लेकिन अब तक ऐसा लगता है कि न्यूमेरिक यूपीडाउन (डब्ल्यूपीएफ द्वारा समर्थित या नहीं) वह कार्यक्षमता प्रदान करने वाला नहीं है जो मुझे चाहिए। जिस तरह से मेरे आवेदन को डिज़ाइन किया गया है, उनके दाहिने दिमाग में कोई भी तीर के साथ गड़बड़ नहीं करना चाहता है। वे मेरे आवेदन के संदर्भ में कोई व्यावहारिक अर्थ नहीं रखते हैं।

इसलिए मैं एक सामान्य तरीका खोज रहा हूं ताकि एक मानक WPF टेक्स्टबॉक्स को केवल उन पात्रों को स्वीकार कर सकें जो मुझे चाहिए। क्या यह संभव है? क्या यह व्यावहारिक है?

जवाबों:


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
यदि आवश्यक हो तो आपका regex वैज्ञानिक संकेतन (1e5) की अनुमति नहीं देता है।
रॉन वारहोलिक

14
ध्यान दें कि यह उत्तर केवल यह बताता है कि आप क्या टाइप करते हैं, इसलिए आप 3-.3 में प्रवेश कर सकते हैं
डेविड साइक्स

153
उत्तर की बात सही रेगेक्स को निर्दिष्ट करने के लिए नहीं थी, यह दिखाने के लिए कि किसी प्रकार को फ़िल्टर करने के लिए WPF का उपयोग कैसे करें।
रे

27
[स्पेस] प्रीव्यूटेक्स्ट इंपुट इवेंट को फायर नहीं करता है।
पीटर

5
कुछ double.TryParse()इसी तरह की लाइनों के साथ संभवत: लागू किया जाएगा और अधिक लचीला होगा।
थॉमस वेलर

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] के रूप में बदलें।
किशोर

संख्या, दशमलव और ऑपरेटर के बारे में क्या?
जेसन एबरसे

कृपया मुझे बताएं कि किसी अन्य STATIC वर्ग में घोषित होने और टेक्स्टबॉक्स पर लागू होने पर इसका उपयोग कैसे करें?
शेखर शाट

3
मुझे यह वास्तविक उत्तर, लघु और सरल से अधिक पसंद है। वास्तविक उत्तर को समान परिणाम प्राप्त करने के लिए दो तरीकों की आवश्यकता होती है।
स्लीवर

1
@ जैगड सुझाया गया उत्तर चिंताओं का बेहतर पृथक्करण है। हालाँकि आप इस मान्यता पर कई टेक्स्टबॉक्स सेट कर सकते हैं। बस 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
इस भयानक समाधान से प्रेरित होकर, मैंने कुछ सुधार लागू किए। कृपया इसे नीचे धागे में देखें।
एलेक्स क्लॉज़

2
नमस्ते। मुझे पता है कि यह थोड़ा देर से है लेकिन मैं इसे लागू करने की कोशिश कर रहा हूं, लेकिन मुझे गलतियां मिलती रहती हैं। मैं अनुमान लगा रहा हूं कि मुझे कुछ संदर्भ याद आ रहे हैं। क्या आपके द्वारा कक्षा बनाने के बाद किसी भी प्रकार की चूक के अलावा टाइप किए जाने वाले हैं?
ऑफर

1
@ ओफ़र हां, अपने xaml विंडो के शीर्ष पर xmlns: अन्तरक्रियाशीलता = " schemas.microsoft.com/expression/2010/interactivity " शामिल करना न भूलें ।
WiteCastle

अभिव्यक्ति अब अप्रचलित है। हालांकि यह दृष्टिकोण साफ है, यह कोड का उपयोग कर रहा है जिसे अब बनाए नहीं रखा जा रहा है।
रॉबर्ट बेकर

1
इसलिए यदि आप लौटने के लिए IsValid फ़ंक्शन को संपादित करते हैं! ExceedsMaxLength (newText, paste) && Regex.IsMatch (String.Concat (this.AssociatedObject.Text, newxtext), RegularExpression); तब यह पूरे स्ट्रिंग का मूल्यांकन करेगा। Btw - व्यवहार के साथ इस विकल्प से प्यार है !!
रोजला

59

यह विल्पी के उत्तर का एक बेहतर समाधान है । मेरे सुधार हैं:

  • डेल और बैकस्पेस बटन पर बेहतर व्यवहार
  • जोड़ा 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अपने कंडिटॉन (this.MaxLength == 0 || text.Length <= this.MaxLength)रिटर्न को सेट नहीं करना false। यह बेहतर होना चाहिए (this.MaxLength == int.MinValue || text.Length <= this.MaxLength)क्योंकि आप int.MinValueडिफ़ॉल्ट मान के रूप में सेट करते हैं MaxLength
क्रिस्टोफ मेयनर

1
धन्यवाद @Christoph, हाँ, आप सही हैं। मैंने अपना उत्तर संशोधित कर लिया है।
एलेक्स

@AlexKlaus जब तक मैं UpdateSourceTrigger=PropertyChangedबंधन में नहीं जोड़ता तब तक यह बहुत अच्छा काम करता है । कोई भी विचार है कि इस कोड को कैसे काम करना है जब इसे बदलना UpdateSourceTriggerहै PropertyChanged? इस कोड को साझा करने के लिए धन्यवाद।
जूनियर

32

यहाँ MVVM का उपयोग करते हुए एक बहुत ही सरल और आसान तरीका है।

व्यू मॉडल में एक पूर्णांक संपत्ति के साथ अपने टेक्स्टबॉक्स को बांधें, और यह एक मणि की तरह काम करेगा ... यह तब भी सत्यापन दिखाएगा जब पाठ बॉक्स में एक गैर-पूर्णांक दर्ज किया जाता है।

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();
    }
}

लेकिन प्रश्न में "मैं अंकों और दशमलव बिंदु को स्वीकार करना चाह रहा हूं" । क्या इस उत्तर के लिए दशमलव बिंदु स्वीकार किया जाता है?
पीटर मोर्टेंसन

मैं बदल रहा है की कोशिश की longकरने के लिए floatहै, लेकिन यह बहुत सही तत्काल सत्यापन के साथ काम नहीं किया। मैंने UpdateSourceTrigger="PropertyChanged"बाइंडिंग में जोड़ा , इसलिए यह वैद्यता को प्रदर्शित करेगा क्योंकि प्रत्येक वर्ण टाइप किया गया था, और अब कोई '' टाइप नहीं कर सकता था। पाठ बॉक्स में जब तक कि कोई अवैध चरित्र मौजूद नहीं था ("1x.234" लिखना था, तब 'x' हटाएं)। यह इस मोड में थोड़ा सुस्त भी महसूस करता है। यह System.Number.ParseSingle()काम करने के लिए उपयोग करने के लिए प्रकट होता है , इसलिए यह कई प्रकार के नोटेशन को स्वीकार करता है।
फादन

@ व्होलल शायद मतदान नहीं कर रहे हैं क्योंकि यह नहीं बताता है कि सत्यापन कैसे काम करता है।
पॉल मैकार्थी

26

एक वैध नियम में जोड़ें ताकि जब पाठ बदले, तो यह निर्धारित करने के लिए जांचें कि क्या डेटा संख्यात्मक है, और यदि यह है, तो प्रसंस्करण जारी रखने की अनुमति देता है, और यदि यह नहीं है, तो उपयोगकर्ता को संकेत देता है कि उस क्षेत्र में केवल संख्यात्मक डेटा स्वीकार किया जाता है।

विंडोज प्रेजेंटेशन फाउंडेशन में मान्यकरण में और पढ़ें


6
यह वास्तव में एसओ मानकों के लिए एक जवाब नहीं है।
रॉबर्ट बेकर

यह ऐसा करने का .net तरीका लगता है।
टेलीमैट

1
है सही जवाब: सत्यापन viene मॉडल या मॉडल स्तर पर होना चाहिए। इसके अलावा आप बस एक संख्यात्मक प्रकार के लिए बाध्य कर सकते हैं doubleऔर जो पहले से ही आपको एक मानक सत्यापन प्रदान कर रहा है।

24

विस्तृत WPF टूलकिट में एक है: NumericUpDown यहां छवि विवरण दर्ज करें


मैंने इस नियंत्रण की कोशिश की है, लेकिन यह अपडेट करने के लिए समस्याएँ देता है जब UpdateSourceTrigger = PropertyChanged के साथ स्पिनर का उपयोग करना और सामान्य रूप से उपयोगकर्ता के लिए वैज्ञानिक संकेतन में प्रवेश करना मुश्किल है।
मेंनो डीज - वैन रिज्स्विज

5
कृपया ध्यान दें कि NumericUpDownअब अप्रचलित है। आप DecimalUpDownअपडेट किए गए टूलकिट विस्तारित WPF टूलकिट कम्युनिटी संस्करण
19

20

बस एक सत्यापन नियम लागू कर सकते हैं और इसे टेक्स्टबॉक्स में लागू कर सकते हैं:

  <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;
    }
}

यदि आप इनपुट दशमलव अंकों को प्राप्त करना चाहते हैं, तो पाठ "में" समाप्त होने पर "वैध" न लौटें। कृपया stackoverflow.com/a/27838893/417939
YantingChen

14

यहाँ मेरे पास रे के उत्तर से प्रेरित एक सरल समाधान है । यह संख्या के किसी भी रूप की पहचान करने के लिए पर्याप्त होना चाहिए।

यदि आप केवल सकारात्मक संख्याएँ, पूर्णांक मान या दशमलव स्थानों की अधिकतम संख्या के लिए सटीक मान चाहते हैं, तो यह समाधान आसानी से संशोधित किया जा सकता है।


जैसा कि रे के उत्तर में सुझाया गया है , आपको पहले एक 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
मुझे यह उत्तर बहुत पसंद है, सरल और प्रभावी +
पल्स

भगवान और सरल लेकिन इसकी बदसूरत है कि यह रिक्त स्थान की अनुमति देता है
मोमो

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);
एनम

7

मैं मान लूंगा कि:

  1. आपका टेक्स्टबॉक्स जिसके लिए आप संख्यात्मक इनपुट की अनुमति देना चाहते हैं, केवल इसकी पाठ संपत्ति शुरू में कुछ मान्य संख्या मान (उदाहरण के लिए, 2.7172) पर सेट है।

  2. आपका टेक्स्टबॉक्स आपके मुख्य विंडो का एक बच्चा है

  3. आपकी मुख्य विंडो क्लास Window1 की है

  4. आपका टेक्स्टबॉक्स नाम संख्यात्मक टीबी है

मूल विचार:

  1. private string previousText;अपनी मुख्य विंडो कक्षा में जोड़ें: (Window1)

  2. जोड़ें: previousText = numericTB.Text;अपने मुख्य विंडो कंस्ट्रक्टर के लिए

  3. कुछ इस तरह से होने के लिए numTB.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;
    }

जब तक यह मान्य है, तब तक यह पिछले टैक्स्ट को न्यूमेरिक टीबी.टीकट पर सेट करता रहेगा, और अगर यूजर इसे पसंद नहीं करते हैं, तो इसके अंतिम वैल्यू के लिए न्यूमेरिक बीटी.टेक्स्ट सेट करें। बेशक, यह सिर्फ मूल विचार है, और यह सिर्फ "बेवकूफ प्रतिरोधी" है, न कि "बेवकूफ सबूत"। यह उस मामले को नहीं संभालता है जिसमें उपयोगकर्ता रिक्त स्थान के साथ गड़बड़ करता है, उदाहरण के लिए। तो यहाँ एक पूर्ण समाधान है जो मुझे लगता है कि "बेवकूफ सबूत" है, और अगर मैं गलत हूं तो कृपया मुझे बताएं:

  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;
                    }
                }
            }
        }
    }

और बस। यदि आपके पास कई TextBoxes हैं, तो मैं एक CustomControl बनाने की सलाह देता हूं जो TextBox से विरासत में मिली है, इसलिए आप पिछलेText और संख्यात्मकTB_TextChanged को एक अलग फ़ाइल में लपेट सकते हैं।


वाह यह बढ़िया है! हालांकि मैं सामने वाले को एक नकारात्मक प्रतीक कैसे दे सकता हूं?
द न्यूबॉयगू

6

यह केवल आवश्यक कोड है:

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

यह केवल संख्याओं को पाठ बॉक्स में इनपुट करने की अनुमति देता है।

दशमलव बिंदु या माइनस साइन की अनुमति देने के लिए, आप नियमित अभिव्यक्ति को बदल सकते हैं [^0-9.-]+


1
एक मामूली नाइटपिक को छोड़कर बहुत अच्छा समाधान: यह आपको व्हाट्सएप में प्रवेश करने से नहीं रोकेगा, क्योंकि वे प्रीव्यू टेक्स्ट इंक्वायरी इवेंट को ट्रिगर नहीं करते हैं।
टिम पोहलमैन

बैकस्पेस इसे भी फायर नहीं करता है।
विंगर सेंडोन

6

यदि आप एक मूल कार्य करने के लिए बहुत सारे कोड नहीं लिखना चाहते हैं (मुझे नहीं पता कि लोग लंबे तरीके क्यों बनाते हैं) तो आप बस यह कर सकते हैं:

  1. नामस्थान जोड़ें:

    using System.Text.RegularExpressions;
  2. XAML में, एक TextChanged संपत्ति सेट करें:

    <TextBox x:Name="txt1" TextChanged="txt1_TextChanged"/>
  3. Txt1_TextChanged विधि के तहत WPF में, जोड़ें Regex.Replace:

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

2
यह एक व्यवहार या एक संलग्नक का उपयोग करने के लिए बहुत साफ है। प्रत्येक दृश्य में / प्रत्येक टेक्स्टबॉक्स के लिए कोई कोड-फ़िदेलिंग नहीं
सर रूफो

काम हो सकता है लेकिन बदसूरत है क्योंकि गाजर टेक्स्टबॉक्स के सामने की स्थिति में कूद जाएगी
मोमो

6

एक अन्य दृष्टिकोण संलग्न व्यवहार का उपयोग करना होगा, मैंने अपना कस्टम टेक्स्टबॉक्स हेल्पर लागू किया वर्ग , जिसका उपयोग मेरी परियोजना के दौरान पर किया जा सकता है। क्योंकि मुझे लगा कि इस उद्देश्य के लिए हर टेक्स्टबॉक्स और प्रत्येक व्यक्ति के लिए XAML फाइल में घटनाओं की सदस्यता लेना समय लेने वाली हो सकती है।

TextBox हेल्पर वर्ग जिसे मैंने लागू किया है, में ये विशेषताएं हैं:

  • फ़िल्टर और केवल डबल , इंट , यूइंट और प्राकृतिक में संख्या को स्वीकार करना प्रारूप
  • फ़िल्टर करना और केवल सम या विषम संख्या को स्वीकार करना
  • हैंडल इवेंट इवेंट हैंडलरअमान्य पाठ को हमारे संख्यात्मक टेक्स्टबॉक्स में चिपकाने से रोकने के लिए को
  • एक डिफ़ॉल्ट मान सेट कर सकते हैं जिसका उपयोग अवैध डेटा को रोकने के लिए किया जाएगा।

यहाँ 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"/>

ध्यान दें कि मेरा TextBox हेल्पर viewHelpers xmlns उर्फ ​​में रहता है।

मुझे उम्मीद है कि यह कार्यान्वयन किसी अन्य के काम को आसान बनाता है :)


1
यह एक DataTemplate के अंदर एक पाठ बॉक्स का उपयोग करते समय बहुत अच्छा है, धन्यवाद!
NucS

3
शानदार जवाब लेकिन मुझे आपके तरीके पढ़ने में मुश्किल लगते हैं। संभवतः आपको उन्हें छोटे लोगों में तोड़ देना चाहिए। देखें कि आपके लिए एक विधि की आदर्श लंबाई क्या है?
एंथोनी

रचनात्मक प्रतिक्रिया के लिए धन्यवाद @Anthony
अमीर महदी नासिरिरी

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

टेक्स्टबॉक्स के पूर्वावलोकन कीडाउन घटना में।


3
हालांकि बैकस्पेस की अनुमति नहीं देता है।
11

2
बैकस्पेस 2 है, टैब 3 है
डैनियल

6
-1 क्योंकि मेरे अनुभव में इस तरह के स्मार्ट ट्रिक्स अंततः आपको गधे में काट देते हैं, जैसा कि कुछ अन्य टिप्पणीकारों ने नोट किया है।
डॉनकेस्टर

बायाँ तीर 23 है, दायाँ तीर 25 है।
हारून

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

2
यह भी डॉट को स्वीकार नहीं करेगा ., क्योंकि e.Textकेवल अंतिम इनपुट चरित्र देता है और एक डॉट IsDigitचेक को विफल कर देगा ।
एंथनी

4

केवल पूर्णांक और दशमलव का उपयोग करके इस प्रकार की समस्या के लिए त्वरित और बहुत सरल कार्यान्वयन की तलाश करने वालों के लिए, अपनी XAML फ़ाइल में, PreviewTextInputअपने TextBoxऔर फिर अपने xaml.cs फ़ाइल के उपयोग के लिए एक संपत्ति जोड़ें :

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

जब तक दूसरों ने उल्लेख किया है, तब तक पूरे स्ट्रिंग की जाँच करते रहना बेमानी है, जैसा कि आप उल्लेख कर रहे हैं, आप वैज्ञानिक संकेतन के साथ कुछ कर रहे हैं (यद्यपि, यदि आप 'ई' जैसे कुछ वर्ण जोड़ रहे हैं, तो प्रतीकों / वर्णों को जोड़ना एक सरल रीगेक्स है) वास्तव में सरल और अन्य उत्तरों में सचित्र)। लेकिन सरल अस्थायी बिंदु मानों के लिए, यह समाधान पर्याप्त होगा।

एक लंबर अभिव्यक्ति के साथ एक लाइनर के रूप में लिखा गया है:

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

3

हम पाठ बॉक्स परिवर्तित घटना पर सत्यापन कर सकते हैं। निम्नलिखित कार्यान्वयन संख्यात्मक और एक दशमलव बिंदु के अलावा अन्य कुंजीपट इनपुट को रोकता है।

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();
    }
});

2

विंडोज फॉर्म में यह आसान था; आप KeyPress के लिए एक घटना जोड़ सकते हैं और सब कुछ आसानी से काम करता है। हालाँकि, WPF में वह घटना नहीं है। लेकिन इसके लिए बहुत आसान तरीका है।

WPF पाठ बॉक्स में 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ऑब्जेक्ट के टेक्स्ट का उपयोग करता है । आप केवल एक बार घटना लिखते हैं और इसे कई टेक्स्टबॉक्स के लिए उपयोग कर सकते हैं।


2

अब मुझे पता है कि इस प्रश्न का एक स्वीकृत उत्तर है , लेकिन व्यक्तिगत रूप से, मुझे यह थोड़ा भ्रमित लगता है और मेरा मानना ​​है कि यह उससे आसान होना चाहिए। इसलिए मैं यह प्रदर्शित करने की कोशिश करूंगा कि मुझे जितना अच्छा काम करना चाहिए, मैं कर पाया:

में Windows Forms , वहाँ एक घटना कहा जाता है KeyPressजो काम के इस प्रकार के लिए पूरी तरह से अच्छा है। लेकिन यह WPF में मौजूद नहीं है , इसलिए इसके बजाय, हम PreviewTextInputघटना का उपयोग करेंगे । इसके अलावा, मान्यता के लिए, मेरा मानना ​​है कि कोई भी इसके foreachमाध्यम से लूप का उपयोग कर सकता है textbox.Textऔर जांच सकता है कि क्या यह मेल खाता है ?) स्थिति, लेकिन ईमानदारी से, यह नियमित अभिव्यक्ति है। लिए है।

पवित्र संहिता में डुबकी लगाने से पहले एक और बात । ईवेंट को निकाल दिया जाए, इसके लिए दो काम कर सकते हैं:

  1. XAML का उपयोग प्रोग्राम को यह बताने के लिए करें कि कौन से फ़ंक्शन को कॉल करना है: <PreviewTextInput="textBox_PreviewTextInput/>
  2. इसे Loadedफॉर्म की स्थिति में करें (जो टेक्स्टबॉक्स में है): 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-बिट पूर्णांक के लिए, एक 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 बाइंडिंग के साथ फ्लोटिंग पॉइंट क्लासेस का उपयोग किया जाता है, तो सुनिश्चित करें कि बाइंडिंग मैंने इस्तेमाल की गई ट्रिपप्रैस विधि से मेल खाने के लिए वर्तमान संस्कृति का उपयोग करती है।



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

एक स्पष्टीकरण क्रम में होगा।
पीटर मोर्टेंसन

1

मैं एक साधारण परियोजना के लिए एक अनबाउंड बॉक्स के साथ काम कर रहा था जिस पर मैं काम कर रहा था, इसलिए मैं मानक बाध्यकारी दृष्टिकोण का उपयोग नहीं कर सका। नतीजतन मैंने एक साधारण हैक बनाया जो दूसरों को मौजूदा टेक्स्टबॉक्स नियंत्रण को विस्तार देने से काफी आसान लग सकता है:

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

कुछ समय के लिए यहां कुछ समाधानों का उपयोग करने के बाद, मैंने अपना खुद का विकास किया जो मेरे एमवीवीएम सेटअप के लिए अच्छी तरह से काम करता है। ध्यान दें कि यह अन्य लोगों में से कुछ के रूप में गतिशील नहीं है, फिर भी उपयोगकर्ताओं को गलत वर्णों में प्रवेश करने की अनुमति देता है, लेकिन यह उन्हें बटन दबाने और इस प्रकार कुछ भी करने से रोकता है। जब कार्रवाई नहीं की जा सकती है तो बटन को ग्रे करने के मेरे विषय के साथ यह अच्छी तरह से चला जाता है।

मेरे पास एक 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"/>

सी#

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;

फ़ाइल के शीर्ष पर और समाधान का निर्माण। न्यूमेरिक टेक्स्ट कंट्रोल तब टूलबॉक्स में सबसे ऊपर दिखाई देगा।


1
NumberValidationTextBox और रेगुलर एक्सप्रेशंस का उपयोग करके पहले के MUCH आसान समाधान देखें। यह मज़ाकीय है।
स्कॉट शॉ-स्मिथ

@ स्कॉटशॉ-स्मिथ शायद स्वीकृत समाधान कम कोड है, लेकिन यह इससे तेज नहीं है। हमेशा कुछ परियोजनाएं होती हैं जिन्हें रेगेक्स का उपयोग करने के बजाय बहुत अधिक प्रसंस्करण शक्ति की आवश्यकता होती है।
बियोन्डो
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.