Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handle a paste event in c#

I've created a static class numeric Textbox but i wan't to control what the users paste in te textbox. For handling paste Event i use textchanged event:

        static public void textChanged(EventArgs e, TextBox textbox, double tailleMini, double tailleMaxi, string carNonAutorisé)
    {            
        //Recherche dans la TextBox, la première occurrence de l'expression régulière.
        Match match = Regex.Match(textbox.Text, carNonAutorisé);
        /*Si il y a une Mauvaise occurence:
         *   - On efface le contenu collé
         *   - On prévient l'utilisateur 
         */
        if (match.Success)
        {
            textbox.Text = "";
            MessageBox.Show("Votre copie un ou des caractère(s) non autorisé", "Attention", MessageBoxButtons.OK, MessageBoxIcon.Information);
        }
        tailleTextBox(textbox, tailleMini, tailleMaxi);
    }

In another class i use this static methode like this

    private void tbxSigné_TextChanged(object sender, EventArgs e)
    {
        FiltreTbx.textChanged(e, tbxSigné, double.MinValue, double.MaxValue, @"[^\d\,\;\.\-]");
    }

What i wan't to do is something like that:

  if (match.Success)
    {
        textbox.Text = //Write the text before users paste in the textbox;

    }

Anyone have an idea please?

like image 295
Sef Avatar asked Apr 13 '13 12:04

Sef


1 Answers

First of all, have you considered using MaskedTextBox instead? It can handle the character filtering for you.

However, for the sake of this exercise, you could think of a solution along this line. This is the usage:

public Form1()
{
    InitializeComponent();

    FiltreTbx.AddTextBoxFilter(tbxSigné,
                               double.MinValue, double.MaxValue,
                               @"[^\d\,\;\.\-]");
}

This AddTextBoxFilter is a new static method, which you only call once. It will add a TextChanged handler to the TextBox. This handler uses a closure to store the previous Text in the text box.

Your static method gained an extra parameter to pass along this previous text.

public class FiltreTbx
{
    public static void AddTextBoxFilter(TextBox textbox,
                                        double tailleMini, double tailleMaxi,
                                        string carNonAutorisé)
    {
        string previousText = textbox.Text;

        textbox.TextChanged +=
            delegate(object sender, EventArgs e)
            {
                 textChanged(e, textbox, tailleMini, tailleMaxi,
                             carNonAutorisé, previousText);
                 previousText = textbox.Text;
            };
    }

    static public void textChanged(EventArgs e, TextBox textbox,
                                   double tailleMini, double tailleMaxi,
                                   string carNonAutorisé, string previousText)
    {
        //Recherche dans la TextBox, la première occurrence de l'expression régulière.
        Match match = Regex.Match(textbox.Text, carNonAutorisé);
        /*Si il y a une Mauvaise occurence:
         *   - On efface le contenu collé
         *   - On prévient l'utilisateur 
         */
        if (match.Success)
        {
            // Set the Text back to the value it had after the previous
            // TextChanged event.
            textbox.Text = previousText;
            MessageBox.Show("Votre copie un ou des caractère(s) non autorisé",
                            "Attention", MessageBoxButtons.OK,
                            MessageBoxIcon.Information);
        }
        tailleTextBox(textbox, tailleMini, tailleMaxi);
    }
}

I'm not sure what tailleTextBox is supposed to do exactly, you did not include that source code, but I suspect it enforces the minimum and maximum values?

Alternate solution

If you want to handle the Paste operation yourself, before it even happens, you will have to intercept the WM_PASTE message to the text box. One way of doing is would be by creating a specialized control:

using System;
using System.Windows.Forms;

class MyTextBox : TextBox
{
    private const int WM_PASTE = 0x0302;

    protected override void WndProc(ref Message m)
    {
        if (m.Msg != WM_PASTE)
        {
            // Handle all other messages normally
            base.WndProc(ref m);
        }
        else
        {
            // Some simplified example code that complete replaces the
            // text box content only if the clipboard contains a valid double.
            // I'll leave improvement of this behavior as an exercise :)
            double value;
            if (double.TryParse(Clipboard.GetText(), out value))
            {
                Text = value.ToString();
            }
        }
    }
}

If you define the class in your WinForms project, you should be able to drag it onto your form like any other control.

like image 144
Thorarin Avatar answered Nov 04 '22 10:11

Thorarin