4

私たちの場合、社会保険 (税) 番号を収集する MaskedTextBox コントロールがあります (マスク リテラルを含む文字列表現のため、ValidatingType はありません)。社会保険番号は、ダッシュで区切られた 3 桁の 3 つのグループです。ダッシュの代わりにスペースを入力または入力する場合があります。

テキストボックスの構成は次のとおりです。

  • マスク:999-999-999
  • ValidationType: null / 不要
  • 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 の場合は、クリップボード テキストのクリーンアップ バージョンを手動で処理して渡します。動作する可能性がありますが、右クリックのコンテキスト メニューからの貼り付けはどうでしょうか。

他のアイデアはありますか?

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

Pasteing イベントを使用して、次のようにスペースを削除します。

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