Numeric Data Entry in WPF

前端 未结 17 2510
情话喂你
情话喂你 2020-12-02 05:38

How are you handling the entry of numeric values in WPF applications?

Without a NumericUpDown control, I\'ve been using a TextBox and handling its PreviewKeyDown eve

相关标签:
17条回答
  • 2020-12-02 05:47
    public class NumericTextBox : TextBox
    {
        public NumericTextBox()
            : base()
        {
            DataObject.AddPastingHandler(this, new DataObjectPastingEventHandler(CheckPasteFormat));
        }
    
        private Boolean CheckFormat(string text)
        {
            short val;
            return Int16.TryParse(text, out val);
        }
    
        private void CheckPasteFormat(object sender, DataObjectPastingEventArgs e)
        {
            var isText = e.SourceDataObject.GetDataPresent(System.Windows.DataFormats.Text, true);
    
            if (isText)
            {
                var text = e.SourceDataObject.GetData(DataFormats.Text) as string;
                if (CheckFormat(text))
                {
                    return;
                }
            }
    
            e.CancelCommand();
        }
    
        protected override void OnPreviewTextInput(System.Windows.Input.TextCompositionEventArgs e)
        {
            if (!CheckFormat(e.Text))
            {
                e.Handled = true;
            }
            else
            {
                base.OnPreviewTextInput(e);
            }
        }
    }
    

    Additionally you may customize the parsing behavior by providing appropriate dependency properties.

    0 讨论(0)
  • 2020-12-02 05:47

    Can you not just use something like the following?

    int numericValue = 0;
    
    if (false == int.TryParse(yourInput, out numericValue))
    {
        // handle non-numeric input
    }
    
    0 讨论(0)
  • 2020-12-02 05:49

    Why don't you just try using the KeyDown event rather than the PreviewKeyDown Event. You can stop the invalid characters there, but all the control characters are accepted. This seems to work for me:

    private void NumericKeyDown(object sender, System.Windows.Input.KeyEventArgs e)
    {
        bool isNumPadNumeric = (e.Key >= Key.NumPad0 && e.Key <= Key.NumPad9);
        bool isNumeric =((e.Key >= Key.D0 && e.Key <= Key.D9) && (e.KeyboardDevice.Modifiers == ModifierKeys.None));
        bool isDecimal = ((e.Key == Key.OemPeriod || e.Key == Key.Decimal) && (((TextBox)sender).Text.IndexOf('.') < 0));
        e.Handled = !(isNumPadNumeric || isNumeric || isDecimal);
    }
    
    0 讨论(0)
  • 2020-12-02 05:50
    Private Sub Value1TextBox_PreviewTextInput(ByVal sender As Object, ByVal e As TextCompositionEventArgs) Handles Value1TextBox.PreviewTextInput
        Try
            If Not IsNumeric(e.Text) Then
                e.Handled = True
            End If
        Catch ex As Exception
        End Try
    End Sub
    

    Worked for me.

    0 讨论(0)
  • 2020-12-02 05:52

    I decided to simplify the reply marked as the answer on here to basically 2 lines using a LINQ expression.

    e.Handled = !e.Text.All(Char.IsNumber);
    base.OnPreviewTextInput(e);
    
    0 讨论(0)
  • 2020-12-02 05:53

    My Version of Arcturus answer, can change the convert method used to work with int / uint / decimal / byte (for colours) or any other numeric format you care to use, also works with copy / paste

    protected override void OnPreviewTextInput( System.Windows.Input.TextCompositionEventArgs e )
    {
        try
        {
            if ( String.IsNullOrEmpty( SelectedText ) )
            {
                Convert.ToDecimal( this.Text.Insert( this.CaretIndex, e.Text ) );
            }
            else
            {
                Convert.ToDecimal( this.Text.Remove( this.SelectionStart, this.SelectionLength ).Insert( this.SelectionStart, e.Text ) );
            }
        }
        catch
        {
            // mark as handled if cannot convert string to decimal
            e.Handled = true;
        }
    
        base.OnPreviewTextInput( e );
    }
    

    N.B. Untested code.

    0 讨论(0)
提交回复
热议问题