4

我有一个 MaskedTextBox 控件,在我们的例子中,它正在收集社会保险(税)号码(虽然没有 ValidatingType,因为字符串表示包括掩码文字)。社会保险号是由破折号分隔的 3 组 3 位数字。有时可以键入或输入空格而不是破折号。

文本框的配置是:

  • 面罩:999-999-999
  • 验证类型:空/不需要
  • 跳过文字:真
  • CutCopyMaskFormat:IncludeLiterals(仅在从文本框剪切/复制时相关)
  • TextMaskFormat:IncludeLiterals

-- 如果您认为还有其他重要的属性,请告诉我!

问题

粘贴以下税号“450 622 097”时,由于空格与掩码不匹配。所以我最终在文本框中输入“450- 62-2 9”。粘贴“450-622-097”将成功粘贴到框中。

我希望能够拦截粘贴事件,以便可能修复它以用破折号替换空格。

或者,我们可以让掩码接受破折号或空格(但总是输出破折号)?

非解决方案

MaskInputRejected 事件 - 我似乎无法处理最初输入的内容(即被拒绝的内容),以便将其与剪贴板顶部的内容进行比较。它只是返回它是如何被拒绝的

验证事件 - 在应用掩码后已经发生。即“450- 62-2 9”的值现在在文本框中。

使用带有静态 Parse 函数的自定义 ValidatingType - 同样,在应用掩码后发生。

检测 Key-Down 事件 - 然后,如果键系列是 Ctrl-V,则手动处理并传入剪贴板文本的清理版本。可以工作,但是通过右键单击上下文菜单粘贴呢?

还有其他想法吗?

4

2 回答 2

3

虽然这是一个锤式解决方案,但面具线存在限制,我看不出有其他解决方法。您需要的是捕获粘贴事件并在文本进入文本框之前对其进行处理。看下面一个简单的例子

   class MyMaskedTextbox : MaskedTextBox
        {
            const int WM_PASTE = 0x0302;

            protected override void WndProc(ref Message m)
            {
                switch (m.Msg)
                {
                    case WM_PASTE:
                        if (Clipboard.ContainsText())
                        {
                            string text = Clipboard.GetText();
                            text = text.Replace(' ', '-');
//put your processing here
                            Clipboard.SetText(text);
                        }
                        break;
                }
                base.WndProc(ref m);
            }
        }
于 2010-05-21T15:02:45.173 回答
1

根据@anchandra 的回复和随后的评论,这里是允许在每个控件的基础上处理文本的类。

public class MyMaskedTextBox : MaskedTextBox
{
    private const int WM_PASTE = 0x0302;

    protected override void WndProc(ref Message m)
    {
        switch (m.Msg)
        {
            case WM_PASTE:
                if (Clipboard.ContainsText())
                {
                    string text = Clipboard.GetText();
                    var args = OnPasting(text);
                    if (args.Cancel)
                    {
                        // Swallow it up!
                        return;
                    }

                    // If value changed, then change what we'll paste from the top of the clipboard
                    if (!args.Value.Equals(text, StringComparison.CurrentCulture))
                    {
                        Clipboard.SetText(args.Value);
                    }
                }
                break;
        }
        base.WndProc(ref m);
    }

    public event EventHandler<PastingEventArgs> Pasting;

    protected virtual PastingEventArgs OnPasting(string value)
    {
        var handler = Pasting;
        var args = new PastingEventArgs(value);
        if (handler != null)
        {
            handler(this, args);
        }
        return args;
    }
}

public class PastingEventArgs : CancelEventArgs
{
    public string Value { get; set; }

    public PastingEventArgs(string value)
    {
        Value = value;
    }
}

并简单地使用粘贴事件来删除空格,如下所示:

private void sinTextBox_Pasting(object sender, PastingEventArgs e)
{
    e.Value = e.Value.Replace(" ", String.Empty);
}
于 2010-05-28T20:32:51.187 回答