17

我有一个不允许输入任何特殊字符的文本框。

用户可以输入:

  1. AZ
  2. 阿兹
  3. 0-9
  4. 空间

我怎样才能使KeyDown活动做到这一点?

4

13 回答 13

31

处理 KeyDown 或 KeyPress 事件是执行此操作的一种方法,但程序员通常会忘记用户仍然可以将无效文本复制并粘贴到文本框中。

一种更好的方法是处理 TextChanged 事件,并删除那里的任何违规字符。这有点复杂,因为您必须跟踪插入符号的位置并在更改框的 Text 属性后将其重新设置到适当的位置。

根据您的应用程序的需要,我会让用户输入他们想要的任何内容,然后在用户尝试提交时标记文本框(将文本变为红色或其他内容)。

于 2009-05-26T11:11:46.187 回答
21

只是想为那些通过搜索结束的人添加一些代码:

private void Filter_TextChanged(object sender, EventArgs e)
{
    var textboxSender = (TextBox)sender;
    var cursorPosition = textboxSender.SelectionStart;
    textboxSender.Text = Regex.Replace(textboxSender.Text, "[^0-9a-zA-Z ]", "");
    textboxSender.SelectionStart = cursorPosition;
}

这是一个更改过滤器,因此可以处理复制和粘贴,并保留光标位置,以便中间更改文本正常工作。

请注意,它使用“发送者”来获取控件名称,允许将这一功能链接到多个文本框,假设它们需要相同的过滤器。您可以通过转到控件的事件部分并手动选择 TextChanged 事件的函数来链接多个控件。

于 2014-03-13T15:08:17.880 回答
9

使用正则表达式过滤掉其他字符。或者使用 Char.IsDigit、IsXXX 方法过滤掉不需要的字符。很多方法可以做到这一点。

更新:如果您必须使用 KeyDown ,那么您似乎还需要处理 KeyPressed 并设置 obEventArgs.Handled = true 以禁止字符。请参阅KeyDown MSDN 页面上的示例

更新:现在您指定它是 WPF。下面的代码将只允许在文本框中输入 az 和 AZ 字符。根据需要扩展...

private void _txtPath_KeyDown(object sender, KeyEventArgs e)
      {
         if ((e.Key < Key.A) || (e.Key > Key.Z))
            e.Handled = true;
      }

如果您将内容复制粘贴到文本框中,这将中断。一旦用户离开控件或单击“确定/提交”,如 MusicGenesis 所说,验证整个文本。

于 2009-05-26T10:50:35.043 回答
3

我认为值得考虑对 TextBox 的 TextChanged 事件进行过滤。您可以创建一个从文本字符串中删除任何无效字符的操作。这比阻止 KeyDown 事件要麻烦一些。

但是,我认为这是要走的路,因为您没有阻止 WPF 的内置 KeyDown/Up 事件处理机制,所以复制/粘贴仍然有效。您将在更高级别的抽象上工作,因此我认为更容易弄清楚发生了什么。

于 2009-05-26T13:15:43.330 回答
3
private void _txtPath_KeyDown(object sender, KeyEventArgs e)
  {
     if ((e.Key < Key.A) || (e.Key > Key.Z))
        e.Handled = true;
  }
于 2009-07-28T03:51:11.227 回答
3

我在silverlight中遇到了这个并写了这样的东西。

private string _filterRegexPattern = "[^a-zA-Z0-9]"; // This would be "[^a-z0-9 ]" for this question.
private int _stringMaxLength = 24;


private void _inputTextBox_TextChanged(object sender, TextChangedEventArgs e)
{
    if (!string.IsNullOrEmpty(_filterRegexPattern))
    {
        var text = _inputTextBox.Text;
        var newText = Regex.Replace(_inputTextBox.Text, _filterRegexPattern, "");

        if (newText.Length > _stringMaxLength)
        {
            newText = newText.Substring(0, _stringMaxLength);
        }


        if (text.Length != newText.Length)
        {
            var selectionStart = _inputTextBox.SelectionStart - (text.Length - newText.Length);
            _inputTextBox.Text = newText;
            _inputTextBox.SelectionStart = selectionStart;
        }
    }
}
于 2013-01-30T21:24:04.397 回答
3

我使用自定义依赖属性来完成此操作。它可用于任何TextBox控件,使用起来比构建关键事件更快、更高效,并使我的代码文件更清晰。

此外,它还可以处理其他不触发按键事件的输入法,例如使用鼠标将值粘贴到 TextBox 中。

自定义 DP 的代码如下所示:

// When set to a Regex, the TextBox will only accept characters that match the RegEx

/// <summary>
/// Lets you enter a RegexPattern of what characters are allowed as input in a TextBox
/// </summary>
public static readonly DependencyProperty AllowedCharactersRegexProperty =
    DependencyProperty.RegisterAttached("AllowedCharactersRegex",
                                        typeof(string), typeof(TextBoxProperties),
                                        new UIPropertyMetadata(null, AllowedCharactersRegexChanged));

// Get
public static string GetAllowedCharactersRegex(DependencyObject obj)
{
    return (string)obj.GetValue(AllowedCharactersRegexProperty);
}

// Set
public static void SetAllowedCharactersRegex(DependencyObject obj, string value)
{
    obj.SetValue(AllowedCharactersRegexProperty, value);
}

// Events
public static void AllowedCharactersRegexChanged(DependencyObject obj, DependencyPropertyChangedEventArgs e)
{
    var tb = obj as TextBox;
    if (tb != null)
    {
        if (e.NewValue != null)
        {
            tb.PreviewTextInput += Textbox_PreviewTextChanged;
            DataObject.AddPastingHandler(tb, TextBox_OnPaste);
        }
        else
        {
            tb.PreviewTextInput -= Textbox_PreviewTextChanged;
            DataObject.RemovePastingHandler(tb, TextBox_OnPaste);
        }
    }
}

public static void TextBox_OnPaste(object sender, DataObjectPastingEventArgs e)
{
    var tb = sender as TextBox;

    bool isText = e.SourceDataObject.GetDataPresent(DataFormats.Text, true);
    if (!isText) return;

    var newText = e.SourceDataObject.GetData(DataFormats.Text) as string;
    string re = GetAllowedCharactersRegex(tb);
    re = string.Format("[^{0}]", re);

    if (Regex.IsMatch(newText.Trim(), re, RegexOptions.IgnoreCase))
    {
        e.CancelCommand();
    }
}

public static void Textbox_PreviewTextChanged(object sender, TextCompositionEventArgs e)
{
    var tb = sender as TextBox;
    if (tb != null)
    {
        string re = GetAllowedCharactersRegex(tb);
        re = string.Format("[^{0}]", re);

        if (Regex.IsMatch(e.Text, re, RegexOptions.IgnoreCase))
        {
            e.Handled = true;
        }
    }
}

它是这样使用的:

<TextBox Text="{Binding SomeValue, UpdateSourceTrigger=PropertyChanged}" 
         local:TextBoxHelpers.AllowedCharactersRegex="a-zA-Z0-9\s" />
于 2014-03-13T16:11:18.130 回答
2

我知道 winForms 有一个 MaskedTextBox 控件,它可以让你准确地指定这种东西。我不知道 WPF,所以我不知道那里是否有,但如果有,那就这样做。它比所有这些带有按键和事件的东西要容易得多,而且也更健壮。

于 2009-05-26T11:59:14.453 回答
2

最简单的方法是包含扩展的 WPF 工具包,它有一个控件,可以通过指定掩码来完全按照您的要求进行操作。

http://wpftoolkit.codeplex.com/wikipage?title=MaskedTextBox&referringTitle=Home

如果需要,它还会在您输入时在文本框中显示掩码。

(它还有许多其他有用的控件)

于 2011-10-14T15:22:50.273 回答
1

并且您的 regExp 可能看起来像 [0-9a-zA-Z]* 以仅允许英文字母数字字符

于 2009-05-26T11:53:11.953 回答
1

只有字母数字文本框 WPF C#,

对不起我的英语..但是对于WPF,c#的这段代码,我只允许字母数字

private void txtTraslado_TextChanged(object sender, KeyEventArgs e)
{
  if (((e.Key < Key.NumPad0)||(e.Key > Key.NumPad9))&&((e.Key < Key.A)||(e.Key > Key.Z)))
  {
    e.Handled = true;
  }
}
于 2011-12-07T17:10:36.250 回答
0

使用 Asp.NET AJAX 控件工具包

<%@ Register Assembly="AjaxControlToolkit" Namespace="AjaxControlToolkit" TagPrefix="asp" %>

并使用 FilteredTextBoxExtender

<asp:TextBox ID="txt_gpf_no" runat="server" CssClass="textbox" 
                                                MaxLength="10"></asp:TextBox>
<asp:FilteredTextBoxExtender ID="FilteredTextBoxExtender_gpf_no" runat="server" Enabled="True"
                                                TargetControlID="txt_gpf_no" FilterType="UppercaseLetters,LowercaseLetters,Custom" ValidChars="1234567890 ">
</asp:FilteredTextBoxExtender>
于 2014-04-05T07:10:28.770 回答
0

在 my.Net Framework 4.5 C# 应用程序中

    private void txtRF_Register_Val_KeyDown(object sender, KeyEventArgs e)
    {
        //only enable alphanumeric
        if (!(((e.KeyCode < Keys.NumPad0) || (e.KeyCode > Keys.NumPad9)) && ((e.KeyCode < Keys.A) || (e.KeyCode > Keys.E))))
        {
            e.SuppressKeyPress = false;
        }
        else
        {
            e.SuppressKeyPress = true;
        }
    }
于 2015-06-24T13:22:43.740 回答