65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF数字值可遮罩文本框

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.76/5 (36投票s)

2009年3月18日

CPOL

3分钟阅读

viewsIcon

216308

downloadIcon

9515

WPF TextBox 的扩展,它只接受数字(整数和浮点数)值。

引言

本文介绍如何增强 WPF TextBox,使其只接受数字(整数和浮点数)值。 第二个目标是让 TextBox 足够智能,从而更容易输入数字。 这是一种简单的方法,可以为 TextBox 提供某种智能,而不仅仅是拒绝非数字符号。 提供的扩展还允许设置最小值和/或最大值。

如果在网上搜索,您可能会找到一些针对此问题的解决方案,其中开发人员通过继承或创建包含标准 WPF TextBox 的自定义/用户控件来创建自己的 TextBox 版本。 大多数其他解决方案都有一个主要缺点 - 您需要将 TextBox 定义替换为新的 MaskTextBox。 有时,这并不痛苦,有时,却很痛苦。 我选择另一种解决方案的原因是在我的情况下,这种更改会很痛苦。

我在此处提出的方法是使用 WPF 附加属性,它基本上类似于依赖属性。 这两者之间的主要区别在于依赖属性是在控件内部定义的,而附加属性是在外部定义的。 例如,TextBox.Text 是一个依赖属性,但 Grid.Column 是一个附加属性。

背景(扩展 TextBox 的功能)

首先,我将定义一个枚举,告诉我们 TextBox 是接受整数、小数还是任何类型的值

public enum MaskType  
{  
   Any,  
   Integer,  
   Decimal  
}

接下来将是附加属性的定义。

public class TextBoxMaskBehavior
{
   public static MaskType GetMask(DependencyObject obj)
   {
      return (MaskType)obj.GetValue(MaskProperty);
   }

   public static void SetMask(DependencyObject obj, MaskType value)
   {
      obj.SetValue(MaskProperty, value);
   }

   public static readonly DependencyProperty MaskProperty =
      DependencyProperty.RegisterAttached(
      "Mask",
      typeof(MaskType),
      typeof(TextBoxMaskBehavior),
      new FrameworkPropertyMetadata(MaskChangedCallback)
      );

   private static void MaskChangedCallback(DependencyObject d, 
                       DependencyPropertyChangedEventArgs e)
   {
      // ...
   }
}

现在,我们像这样指定 WPF TextBox 的掩码

<TextBox local:TextBoxMaskBehavior.Mask="Integer" />

<TextBox local:TextBoxMaskBehavior.Mask="Decimal" />

我们的假设是,特定的 TextBox 将分别接受整数和小数值。 无论何时设置 TestBoxMaskBehavior.Mask,都会调用 MaskChangedCallback。 我们将在那里添加相应的处理。

背景(订阅 TextBox 更改)

WPF TextBox 带有事件:PreviewTextInput,它允许监听文本输入。 它还允许通过将 TextCompositionEventArgsHandled 属性设置为 true 来取消特定的文本输入。 下面是一个说明性示例

<TextBox PreviewTextInput="TextBox_PreviewTextInput" />

C# 代码

private static void TextBox_PreviewTextInput(object sender, 
        System.Windows.Input.TextCompositionEventArgs e)
{
   try
   {
      Convert.ToInt32(e.Text);
   }
   catch
   {
      e.Handled = true;
   }
}

请注意,此代码只是 PreviewTextInput 事件用法的示例。 我的解决方案具有更多有用的功能,而不仅仅是检查输入文本是否为数字 :)。

DataObject.AddPastingHandler(myTextBox, TextBoxPastingEventHandler);
//...
private void TextBoxPastingEventHandler(object sender, DataObjectPastingEventArgs e)
{
   string clipboard = e.DataObject.GetData(typeof(string)) as string;
   try
   {
      Convert.ToInt32(clipboard);
   }
   catch
   {
      e.CancelCommand();
      e.Handled = true;
   }
}

我认为这是不言自明的 :)。

可屏蔽文本框

我们已经介绍了我在解决方案中使用的技术。 完整的源代码和演示二进制文件可以从上面的链接获得。 以下是我的可屏蔽文本框的可用功能列表

  • 拒绝数字、负号和小数分隔符以外的符号。
  • 如果指定了任何最小值/最大值,则限制在最小值/最大值之间。
  • 当键入负号时,无论插入符号的位置如何,如果不存在则在开头添加,或者删除现有的负号。
  • 当键入小数分隔符时,删除现有的分隔符(如果存在),并将新的分隔符放在正确的位置。
  • 还有更多有用的东西。 尝试使用它。 我相信你不会后悔的。

Origin

本文的来源可以在 WPF 数字值可屏蔽文本框找到。

© . All rights reserved.