天天看點

[C#]一個隻能接收某些字元的textbox

經常某些輸入的文本要求隻能是數字等,比如qq登陸框上的qq帳号,如果按鍵不是數字,則沒有反應。原理當然是很簡單的,隻需要在相應消息到來時阻止控件去處理消息即可。

這種例子很多,當然可以override keypress事件。也可以從textbox繼承一個類,然後重寫wndpro,進而無視某些消息。

最重要的消息是WM_CHAR。此外,還有幾個特殊按鍵是永遠不能屏蔽的,分别是backspace, delete,此外還有快捷鍵,ctrl-a,

ctrl-c,ctrl-x,ctrl-v.再此外,我們還要在執行粘貼時對文本做一次判斷,不合法文本則被忽略。

可以用一個FilterString的string來記錄合法字元,不在此字元串中認為是不接受的字元,

       /// <summary>

        /// 覆寫視窗過程!處理WM_CHAR消息!

        /// </summary>

        /// <param name="m"></param>

        protected override void WndProc(ref Message m)

        {

            int charcode = (int)m.WParam;

            switch (m.Msg)

            {

                case WM_CHAR:

                    // 遇到非法字元,直接return即可過濾非法字元!break表示處理該字元

                    //屏蔽小數點

                    if (charcode == (int)Keys.Decimal)

                        return;

                    // 注意delete,backspace字元不能過濾!!!

                    // ctrl-a,ctrl-c,ctrl-v快捷鍵操作不能屏蔽!

                    if (charcode == (int)Keys.Back || charcode == (int)Keys.Delete)

                        break;

                    //如果按下了CTRL鍵

                    if (charcode == 1     //ctrl a

                        || charcode == 3   //ctrl c

                        || charcode == 22  //ctrl v

                        || charcode == 24    //ctrl x

                        )

                    if (this.m_FilterStr.IndexOf((char)charcode) < 0)

                    break;

                case WM_KEYDOWN:

                    //ctrl-A 全選

                    if (Control.ModifierKeys == Keys.Control)

                    {

                        if(charcode==(int)Keys.A)

                            this.SelectAll();

                    }

                case WM_PASTE:

                    //粘貼消息

                    IDataObject obj = Clipboard.GetDataObject();

                    if (obj == null)

                    if (obj.GetDataPresent(DataFormats.Text))

                        string text = obj.GetData(DataFormats.Text) as string;

                        if (text == null)

                            return;

                        foreach (char c in text)

                        {

                            //檢視是否含有過濾字元以外的字元!

                            if (this.m_FilterStr.IndexOf(c) < 0)

                                return;

                        }

            }            

            //處理消息

            base.WndProc(ref m);

        }

今天有些迷糊,主要是發現隻處理wm_char時,ctrl-a快捷鍵失效了,于是在keydown裡面手工實作了全選。具體原因也沒認真去研究,另外一個問題是發現對小數點的屏蔽‘.’無效,原因也不詳,好像按'.'的時候沒産生wm_char消息就直接被處理掉了。郁悶。先就這樣吧,不是很優美。