代码之家  ›  专栏  ›  技术社区  ›  Reddog

winforms maskedtextbox-重新格式化粘贴的文本以匹配掩码

  •  4
  • Reddog  · 技术社区  · 15 年前

    我有一个maskedtextbox控件,在我们的例子中,它正在收集社会保险(税务)号码(但由于字符串表示包括mask文本,所以没有validatingType)。社会保险号码是3组3位数字,用破折号隔开。有时可以键入或输入空格而不是破折号。

    文本框的配置为:

    • 面罩:999-999-999
    • validationType:空/不需要
    • Skipliterals:正确
    • CutCopyMaskFormat:includeInterals(仅当从文本框剪切/复制时相关)
    • 文本屏蔽格式:INCLUDELITERALS

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

    问题

    粘贴以下税号“450 622 097”时,由于空格,它与遮罩不匹配。所以我在文本框中以“450-62-29”结尾。粘贴“450-622-097”将成功粘贴到框中。

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

    或者,我们可以让遮罩接受破折号或空格(但始终输出破折号)?

    非解

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

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

    对静态分析函数使用自定义验证类型-同样,在应用了掩码之后发生。

    正在检测向下键事件-然后,如果键序列是ctrl-v,则手动处理并传入清理过的剪贴板文本版本。可以,但是通过右键单击上下文菜单粘贴呢?

    还有其他想法吗?

    2 回复  |  直到 15 年前
        1
  •  3
  •   anchandra    15 年前

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

       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);
                }
            }
    
        2
  •  1
  •   Reddog    15 年前

    根据@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);
    }
    
    推荐文章