简体   繁体   中英

How to create numeric Textbox Custom Control with dependency Property in WPF?

I want create a custom control for Numeric Text box with dependency property in WPF , in my solution , I add one WPF application and custom control (WPF) ,then in public class , I create dependency property ....

Now I don't know how can i write my rule for text box and which event is true?

Another question : What is my rule for numeric text box , that this text box must be give number and . and Separating .this custom Text box is for accounting system.

public static readonly DependencyProperty NumberTextbox; 
static Numeric()
{
    DefaultStyleKeyProperty.OverrideMetadata(typeof(Numeric), new FrameworkPropertyMetadata(typeof(Numeric)));
    FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata("Enter Your Text", OnKeyDown);
    NumberTextbox =DependencyProperty.Register("Text", typeof(TextBox), typeof(FrameworkElement), metadata);
}


public string NumberTXT
{
    get { return (string)GetValue(NumberTextbox); }
    set { SetValue(NumberTextbox, value); }
} 

I recommend to you add another Dependency Property in example code below I named it Value Also format your number by comma or NumberFormatInfo.CurrentInfo.NumberDecimalSeparator and control caret location changes by two property SelectionLength and SelectionStart. Finally for more detail and complete code WPF Maskable Number Entry TextBox

region Value property

    public static readonly DependencyProperty ValueProperty =
        DependencyProperty.Register("Value", typeof(double), typeof(NumericTextBox), new PropertyMetadata(new Double(), OnValueChanged));

    private static void OnValueChanged(DependencyObject sender, DependencyPropertyChangedEventArgs args)
    {
        //var numericBoxControl = (NumericTextBox)sender;
    }
    public double Value
    {
        get { return (double)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); Text = value.ToString("###,###,###"); }
    }

endregion

    protected override void OnPreviewTextInput(TextCompositionEventArgs e)
    {
        base.OnPreviewTextInput(e);
        var txt = e.Text.Replace(",", "");
        e.Handled = !IsTextAllowed(txt);
        if (IsTextAllowed(txt))
        {
            if (Text.Length == 3)
            {
                Text = Text.Insert(1,",");
                SelectionLength = 1;
                SelectionStart += Text.Length;
            }
        }
    }

    protected override void OnPreviewKeyDown(KeyEventArgs e)
    {
        base.OnPreviewKeyDown(e);
        if (e.Key == Key.Back)
        {
            if (Text.Length == 5)
            {
                Text = Text.Replace(",", "");
                SelectionLength = 1;
                SelectionStart += Text.Length;
            }
        }
    }



    protected override void OnTextChanged(TextChangedEventArgs e)
    {            
        var txt = Text.Replace(",", "");
        SetValue(ValueProperty, txt.Length==0?0:double.Parse(txt));
        base.OnTextChanged(e);
    }

    private static bool IsTextAllowed(string text)
    {
        try
        {
            double.Parse(text);
            return true;
        }
        catch (FormatException)
        {
            return false;
        }
    }

I don't understand your question exactly and why you need dependency proerties to make a numeric text box custom control. What you can do is to inherit from textbox and handle the PreviewTextInput, like it is solved in this question by Ray :

then you get:

  public class NumericTextBox : TextBox
  {

    public NumericTextBox()
    {
      PreviewTextInput += NumericTextBox_PreviewTextInput;
    }

    void NumericTextBox_PreviewTextInput(object sender, System.Windows.Input.TextCompositionEventArgs e)
    {
      e.Handled = !isTextAllowed(e.Text);
    }

    private static bool isTextAllowed(string text)
    {
      var regex = new Regex("[^0-9]+");
      return !regex.IsMatch(text);
    }
  }

And you can use it like that:

 <myNameSpace:NumericTextBox />

And now you can add any other validation you want.

I would also implement a solution for the pasting issue, something like (see also in the link):

private void textBoxPasting(object sender, DataObjectPastingEventArgs e)
    {
      if (e.DataObject.GetDataPresent(typeof(String)))
      {
        var text = (String)e.DataObject.GetData(typeof(String));
        if (!isTextAllowed(text))
        {
          e.CancelCommand();
        }
      }
      else
      {
        e.CancelCommand();
      }
    }

Good job, but let me do the following task with a UserControl in C #:

using System;
using System.Collections.Generic;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace NumericBox
{
    public partial class NumericBox : TextBox
    {
        public NumericBox
        {
            this.TextAlign = HorizontalAlignment.Right;
            this.Text = "0,00";
            this.KeyPress += NumericBox_KeyPress;
        }

        public double NumericResult
        {
            get{
                double d = Convert.ToDouble(this.Text.Replace('.', ','));
                return d;
            }
        }
        private void NumericBox_KeyPress(object sender, KeyPressEventArgs e)
        {
            if (!char.IsControl(e.KeyChar) && !char.IsDigit(e.KeyChar) && (e.KeyChar != '.'))
                e.Handled = true;

            if ((e.KeyChar == '.' && (sender as TextBox).Text.IndexOf('.') > -1))
                e.Handled = true;

            if (e.KeyChar == 13)
            {
                e.Handled = true;
                SendKeys.Send("{TAB}");
            }
        }
    }
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM