Winforms MaskedTextBox - 重新格式化粘贴的文本以匹配蒙版

发布于 2024-09-02 21:03:35 字数 885 浏览 2 评论 0原文

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

文本框的配置为:

  • Mask: 999-999-999
  • ValidationType: null / not required
  • SkipLiterals: true
  • CutCopyMaskFormat: IncludeLiterals(仅在从文本框剪切/复制时相关)
  • TextMaskFormat: IncludeLiterals

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

问题

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

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

或者,我们可以使掩码接受破折号或空格(但始终输出破折号)吗?

非解决方案

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

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

将自定义 ValidatingType 与静态解析函数结合使用 - 再次发生在应用掩码之后。

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

还有其他想法吗?

I have a MaskedTextBox control that, in our case, is collecting social insurance (tax) numbers (without a ValidatingType though since the string representation including the mask literals). A social insurance number is 3 groups of 3 digits separated by dashes. Sometimes spaces may be typed or entered instead of the dashes.

The configuration of the textbox is:

  • Mask: 999-999-999
  • ValidationType: null / not required
  • SkipLiterals: true
  • CutCopyMaskFormat: IncludeLiterals (only relevant when cut/copy FROM textbox)
  • TextMaskFormat: IncludeLiterals

-- Let me know if there other properties that you think could be important!

Problem

When pasting the following tax number "450 622 097" because of the spaces it doesn't match the mask. So I end up with "450- 62-2 9" in the text box. Pasting "450-622-097" will successfully paste into the box.

I want to be able to intercept the paste event in order to possibly fix it up to replace the spaces with dashes.

Alternatively, could we make the mask accept dashes OR spaces (but always output dashes)?

Non-solutions

MaskInputRejected event - I can't seem to get a handle on what was originally input (i.e. what's being rejected) so as to compare it with what's sitting at the top of the Clipboard. It merely returns how it was rejected

Validating event - Already occurs after the mask has been applied. I.e. the value of "450- 62-2 9" is in the textbox now.

Use custom ValidatingType with static Parse function - Again, occurs after the mask has been applied.

Detecting Key-Down event - Then if key series is Ctrl-V then manually handle and pass in a cleaned up version of the clipboard text. Could work, but then what about paste via the right click context menu?

Any other ideas?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

情何以堪。 2024-09-09 21:03:35

虽然这是一个锤子解决方案,但掩码字符串有限制,我没有看到其他解决方法。您需要的是捕获粘贴事件并在文本进入文本框之前对其进行处理。请参阅下面的一个简单示例

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

While this is a hammer solution, there are limitations to the mask string and i don't see another way around it. What you need is to capture the paste event and process the text before it gets in the textbox. See below a simplistic example

   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);
            }
        }
桃气十足 2024-09-09 21:03:35

根据 @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);
}

As per @anchandra's response and subsequent comments here is the class to enable processing of the text on a per-control basis.

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

And simple usage of the Pasting event to strip out spaces as per:

private void sinTextBox_Pasting(object sender, PastingEventArgs e)
{
    e.Value = e.Value.Replace(" ", String.Empty);
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文