【问题标题】:Validation in textbox in WPFWPF文本框中的验证
【发布时间】:2009-08-28 12:28:15
【问题描述】:

我目前正在开发一个 WPF 应用程序,我希望在其中拥有一个只能包含数字条目的 TextBox。我知道当我失去焦点并阻止内容为数字时,我可以验证它的内容,但在其他 Windows 窗体应用程序中,我们使用完全阻止除数字之外的任何输入被写下。另外,我们习惯于将该代码放在一个单独的 dll 中,以便在许多地方引用它。

这是 2008 年未使用 WPF 的代码:

Public Shared Sub BloquerInt(ByRef e As System.Windows.Forms.KeyPressEventArgs, ByRef oTxt As Windows.Forms.TextBox, ByVal intlongueur As Integer)
    Dim intLongueurSelect As Integer = oTxt.SelectionLength
    Dim intPosCurseur As Integer = oTxt.SelectionStart
    Dim strValeurTxtBox As String = oTxt.Text.Substring(0, intPosCurseur) & oTxt.Text.Substring(intPosCurseur + intLongueurSelect, oTxt.Text.Length - intPosCurseur - intLongueurSelect)

    If IsNumeric(e.KeyChar) OrElse _
       Microsoft.VisualBasic.Asc(e.KeyChar) = System.Windows.Forms.Keys.Back Then
        If Microsoft.VisualBasic.AscW(e.KeyChar) = System.Windows.Forms.Keys.Back Then
            e.Handled = False
        ElseIf strValeurTxtBox.Length < intlongueur Then
            e.Handled = False
        Else
            e.Handled = True

        End If
    Else
        e.Handled = True
    End If

WPF 中是否有等效的方法?我不介意这是一种风格,但我是 WPF 的新手,所以风格对于他们能做什么或不能做什么有点模糊。

【问题讨论】:

    标签: wpf validation textbox numeric


    【解决方案1】:

    您可以仅使用 TextBox 上的附加属性将输入限制为数字。定义一次附加属性(即使在单独的 dll 中)并在任何 TextBox 上使用它。这是附加的属性:

       using System;
       using System.Windows;
       using System.Windows.Controls;
       using System.Windows.Input;
    
       /// <summary>
       /// Class that provides the TextBox attached property
       /// </summary>
       public static class TextBoxService
       {
          /// <summary>
          /// TextBox Attached Dependency Property
          /// </summary>
          public static readonly DependencyProperty IsNumericOnlyProperty = DependencyProperty.RegisterAttached(
             "IsNumericOnly",
             typeof(bool),
             typeof(TextBoxService),
             new UIPropertyMetadata(false, OnIsNumericOnlyChanged));
    
          /// <summary>
          /// Gets the IsNumericOnly property.  This dependency property indicates the text box only allows numeric or not.
          /// </summary>
          /// <param name="d"><see cref="DependencyObject"/> to get the property from</param>
          /// <returns>The value of the StatusBarContent property</returns>
          public static bool GetIsNumericOnly(DependencyObject d)
          {
             return (bool)d.GetValue(IsNumericOnlyProperty);
          }
    
          /// <summary>
          /// Sets the IsNumericOnly property.  This dependency property indicates the text box only allows numeric or not.
          /// </summary>
          /// <param name="d"><see cref="DependencyObject"/> to set the property on</param>
          /// <param name="value">value of the property</param>
          public static void SetIsNumericOnly(DependencyObject d, bool value)
          {
             d.SetValue(IsNumericOnlyProperty, value);
          }
    
          /// <summary>
          /// Handles changes to the IsNumericOnly property.
          /// </summary>
          /// <param name="d"><see cref="DependencyObject"/> that fired the event</param>
          /// <param name="e">A <see cref="DependencyPropertyChangedEventArgs"/> that contains the event data.</param>
          private static void OnIsNumericOnlyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
          {
             bool isNumericOnly = (bool)e.NewValue;
    
             TextBox textBox = (TextBox)d;
    
             if (isNumericOnly)
             {
                textBox.PreviewTextInput += BlockNonDigitCharacters;
                textBox.PreviewKeyDown += ReviewKeyDown;
             }
             else
             {
                textBox.PreviewTextInput -= BlockNonDigitCharacters;
                textBox.PreviewKeyDown -= ReviewKeyDown;
             }
          }
    
          /// <summary>
          /// Disallows non-digit character.
          /// </summary>
          /// <param name="sender">The source of the event.</param>
          /// <param name="e">An <see cref="TextCompositionEventArgs"/> that contains the event data.</param>
          private static void BlockNonDigitCharacters(object sender, TextCompositionEventArgs e)
          {
             foreach (char ch in e.Text)
             {
                if (!Char.IsDigit(ch))
                {
                   e.Handled = true;
                }
             }
          }
    
          /// <summary>
          /// Disallows a space key.
          /// </summary>
          /// <param name="sender">The source of the event.</param>
          /// <param name="e">An <see cref="KeyEventArgs"/> that contains the event data.</param>
          private static void ReviewKeyDown(object sender, KeyEventArgs e)
          {
             if (e.Key == Key.Space)
             {
                // Disallow the space key, which doesn't raise a PreviewTextInput event.
                e.Handled = true;
             }
          }
       }
    

    这里是如何使用它(用你自己的命名空间替换“控件”):

    <TextBox controls:TextBoxService.IsNumericOnly="True" />
    

    【讨论】:

    • 我会试试的。我想我几乎可以添加任何类似的东西。比如里面文字的最大长度,这也是我遇到的另一个问题。
    • 忘了说了,是浮点数的最大长度(小数的最大个数和整数部分的最大个数)
    • 是的,附加属性非常强大,允许您添加所有类型的行为。
    • 侧节点:BlockNonDigitCharacters 方法可升级为:if (e.Text.Any(ch =&gt; !Char.IsDigit(ch))) e.Handled = true;
    • 该解决方案充其量是不完整的。它不处理使用 Ctrl+V 或上下文菜单从剪贴板粘贴,用鼠标拖动文本。 Topic starter 的代码也有同样的缺陷,但它并没有让这段代码变得更好。 -1 直到修复。
    【解决方案2】:

    您可以在绑定中添加验证

    <TextBox>
             <TextBox.Text>
                  <Binding Path="CategoriaSeleccionada.ColorFondo"
                           UpdateSourceTrigger="PropertyChanged">
                         <Binding.ValidationRules>
                               <utilities:RGBValidationRule />
                         </Binding.ValidationRules>
                   </Binding>
             </TextBox.Text>
    </TextBox>
    

    看看这个例子(我的程序),你把验证放在绑定中,就像这样。使用 UpdateSourceTrigger,您可以更改绑定的更新时间(失去焦点,在每次更改中...)

    嗯,验证是一个类,我给你举个例子:

    class RGBValidationRule : ValidationRule
    {
        public override ValidationResult Validate(object value, System.Globalization.CultureInfo cultureInfo)
        {
            // Here you make your validation using the value object.
            // If you want to check if the object is only numbers you can
            // Use some built-in method
            string blah = value.ToString();
            int num;
            bool isNum = int.TryParse(blah, out num);
    
            if (isNum) return new ValidationResult(true, null);
            else return new ValidationResult(false, "It's no a number");
        }
    }
    

    简而言之,在该方法中完成工作并返回一个新的 ValidationResult。第一个参数是一个布尔值,如果验证良好,则为 true,否则为 false。第二个参数只是一个信息消息。

    我认为这是文本框验证的基础。

    希望对您有所帮助。

    编辑:抱歉,我不了解 VB.NET,但我认为 C# 代码非常简单。

    【讨论】:

    • 我都知道,所以我很容易理解它。谢谢,我会尽快尝试。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-21
    • 1970-01-01
    • 2014-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多