如何在WPF中创建具有依赖项属性的数字文本框自定义控件?

时间:2015-08-10 04:56:26

标签: c# wpf dependency-properties

我想在WPF中创建一个带有依赖属性的数字文本框的自定义控件,在我的解决方案中,我添加一个WPF应用程序和自定义控件(WPF),然后在公共类中,我创建依赖属性....

现在我不知道如何为文本框编写规则以及哪个事件属实?

另一个问题:数字文本框的规则是什么,此文本框必须为数字分隔 .this自定义文本框用于会计系统。

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

3 个答案:

答案 0 :(得分:2)

我建议您在下面的示例代码中添加另一个Dependency Property,我将其命名为Value 还可以使用逗号或NumberFormatInfo.CurrentInfo.NumberDecimalSeparator格式化数字 并通过两个属性SelectionLength和SelectionStart控制插入符号位置。 最后是更详细和完整的代码WPF Maskable Number Entry TextBox

区域值属性

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

答案 1 :(得分:1)

我完全不明白你的问题,为什么你需要依赖项属性来制作一个数字文本框自定义控件。你可以做的是继承文本框并处理PreviewTextInput,就像它在this question by Ray中解决一样:

然后你得到:

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

你可以这样使用它:

 <myNameSpace:NumericTextBox />

现在您可以添加任何其他所需的验证。

我还会为粘贴问题实现一个解决方案,例如(参见链接):

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

答案 2 :(得分:0)

干得好,但是让我用C#中的UserControl来完成以下任务:

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