熱點推薦:
您现在的位置: 電腦知識網 >> 編程 >> .NET編程 >> 正文

C#中只接受數字輸入的控件

2013-11-13 09:49:25  來源: .NET編程 

  在MFC裡需要獲取文本輸入時經常會用到CEdit或者它的子類可以通過設置它的Edit Control Styles來控制Edit控件的一些行為例如說設置ES_NUMBER標識使控件只允許接受數字(雖然可以復制粘貼非數字字符串到這個控件中)

  在NET中用於獲取文本輸入的控件是TextBox但TextBox本身並不包含可以直接調用的方法或屬性來將其設置為只接受數字輸入這個問題有好幾種方法來解決

  繼承TextBox並覆蓋其CreateParams屬性對該屬性的Style成員添加ES_NUMBER標識 這個方法與MFC中用Edit Control Styles來初始化CEdit一樣可以說是最偷懶的方法

  自行監聽TextBox的KeyDown事件實現輸入驗證(但不保證復制粘貼輸入的正確性) 其實設置ES_NUMBER做的也是這件事如果要實現的功能與Windows控件中默認的一樣的話沒必要自己監聽KeyDown事件如果需要些額外的功能例如說允許輸入負數十六進制數等默認沒有的功能時則監聽KeyDown事件是個有效的方式

  使用第三方編寫的繼承自TextBox的控件 這是擁有不重復發明輪子精神的人們的做法既然獲取數字輸入應該是個常見問題之前也肯定有人解決過那麼利用別人的解決方案就行

  光是CodeProject上就有好幾個與這個相關的實現

  Validating Edit Controls包括了NumericTextBoxAlphanumericTextBoxDateTextBox等許多版本的TextBox子類值得一看

  A numeric textbox with a twist

  Numeric TextBox Allow your users to enter numeric data the easy way

  使用MaskedTextBox 控件 這是NET Framework自帶的一個TextBox的子類實現了一個帶過濾功能的TextBox可以自定義接受的輸入內容的格式只要設置其string Mask屬性即可如果覺得ES_NUMBER的功能不夠用而自行監聽KeyDown事件來做驗證不夠優雅的話這個MaskedTextBox絕對是值得考慮的選擇例如說要接受的數字只要把Mask屬性設為就行(意味著六位的可選十進制數字一個小數點和兩位必須輸入的小數)MSDN上對這個控件有個簡單的walkthrough

  使用NumericUpDown控件   當需要獲取簡單數字輸入時NET世界中最直接的方法不是去想辦法與TextBox搏斗而應該換個控件來用——NumericUpDown這個控件不但能接受來自鍵盤的數字輸入還有一組上下箭頭來步進它包含了許多可以設置的屬性例如顯示分隔符逗號的bool ThousandsSeparator控制最小/最大值的decimal Minimum/decimal Maximum屬性等

  下面對這幾種解決方法的其中一些稍微討論一下

  繼承TextBox並覆蓋其CreateParams屬性

  使用這種方法的NumericTextBox的實現(代碼的第行)及用例

  C#代碼

public class NumericTextBox : SystemWindowsFormsTextBox
{
    private const int ES_NUMBER = x; // ( defined in WinUserh )

  protected override SystemWindowsFormsCreateParams CreateParams {
        get {
            SystemWindowsFormsCreateParams cp = baseCreateParams;
            cpStyle |= ES_NUMBER;
            return cp;
        }
    }
}

  #region use case code sample

  sealed class TestForm : SystemWindowsFormsForm
{
    private NumericTextBox m_ntxt;

  public TestForm() {
        InitializeComponent();
    }

  private void InitializeComponent() {
        thism_ntxt = new NumericTextBox();
        thism_ntxtDock = SystemWindowsFormsDockStyleFill;

  thisClientSize = new SystemDrawingSize( );
        thisControlsAdd(thism_ntxt);
        thisPerformLayout();
    }

  [SystemSTAThread]
    static void Main(string[] args) {
        SystemWindowsFormsApplicationEnableVisualStyles();
        SystemWindowsFormsApplicationSetCompatibleTextRenderingDefault(false);
        SystemWindowsFormsApplicationRun(new TestForm());
    }
}

  #endregion

  運行程序在輸入任意非的字符時的樣子

  

  (截圖反映的是在我的簡體中文Windows XP上的運行效果若系統語言不是簡體中文的話會根據系統語言而不同)

  如果這個文本框已經能滿足需求就沒必要自己監聽KeyDown事件那麼麻煩了

  自行監聽KeyDown事件

  可以參考CodeProject上Numeric TextBox Allow your users to enter numeric data the easy way的實現方式基本原理就是在KeyDown的響應方法中對eKeyCode進行判斷如果輸入不滿足條件則設置某個標識然後再KeyPress的響應方法裡設置eHandled = true來取消該次事件

  最簡單來說類似這樣

  C#代碼

using System;
using SystemDrawing;
using SystemWindowsForms;

  sealed class TestForm : Form
{
    private TextBox m_textBox;
    private bool m_nonNumberEntered = false;

  public TestForm() {
        InitializeComponent();
    }

  private void InitializeComponent() {
        thism_textBox = new TextBox();
        thism_textBoxDock = DockStyleFill;
        thism_textBoxKeyDown += m_textBox_KeyDown;
        thism_textBoxKeyPress += m_textBox_KeyPress;

  thisClientSize = new Size( );
        thisControlsAdd(thism_textBox);
        thisPerformLayout();
    }

  private void m_textBox_KeyDown(object sender KeyEventArgs e) {
        // Initialize the flag to false
        m_nonNumberEntered = false;

  // Determine whether the keystroke is a number from the top of the keyboard
        if (eKeyCode < KeysD || eKeyCode > KeysD) {
            // Determine whether the keystroke is a number from the keypad
            if (eKeyCode < KeysNumPad || eKeyCode > KeysNumPad) {
                // Determine whether the keystroke is a backspace
                if(eKeyCode != KeysBack) {
                    // A nonnumerical keystroke was pressed
                    // Set the flag to true and evaluate in KeyPress event
                    m_nonNumberEntered = true;
                }
            }
        }
    }

  private void m_textBox_KeyPress(object sender KeyPressEventArgs e) {
        // Check for the flag being set in the KeyDown event
        if (m_nonNumberEntered) {
            // Stop the character from being entered into the control
            // since it is nonnumerical
            eHandled = true;
        }
    }

  [STAThread]
    static void Main(string[] args) {
        ApplicationEnableVisualStyles();
        ApplicationSetCompatibleTextRenderingDefault(false);
        ApplicationRun(new TestForm());
    }
}

  (判斷邏輯來自KeyEventArgs在MSDN文檔上的范例代碼)

  得到的文本框外觀與一般的TextBox沒區別只是無法由鍵盤輸入數字字符以外的字符要避免任意字符串被復制粘貼進來的話要另外做些判斷這裡就不詳細寫了

  使用MaskedTextBox

  使用例子

  C#代碼

using System;
using SystemWindowsForms;

  sealed class TestForm : Form
{
    private MaskedTextBox m_maskedTextBox;
    private ToolTip m_toolTip;

  public TestForm() {
        InitializeComponent();
    }

  private void InitializeComponent() {
        thism_maskedTextBox = new MaskedTextBox();
        thism_maskedTextBoxMask = ;
        thism_maskedTextBoxDock = DockStyleFill;
        thism_maskedTextBoxMaskInputRejected += m_maskedTextBox_InputRejected;
        thism_maskedTextBoxKeyDown += m_maskedTextBox_KeyDown;

  thism_toolTip = new ToolTip();

  thisClientSize = new Size( );
        thisControlsAdd(thism_maskedTextBox);
        thisPerformLayout();
    }

  private void m_maskedTextBox_InputRejected(object sender
        MaskInputRejectedEventArgs e) {
        toolTipToolTipTitle = Invalid Input;
        toolTipShow(Only digits () are allowed
            m_maskedTextBox m_maskedTextBoxLocation );
    }

  private void m_maskedTextBox_KeyDown(object sender KeyEventArgs e) {
        m_toolTipHide(maskedTextBox);
    }

  [STAThread]
    static void Main(string[] args) {
        ApplicationEnableVisualStyles();
        ApplicationSetCompatibleTextRenderingDefault(false);
        ApplicationRun(new TestForm());
    }
}

  這段代碼是手寫的要是用VS/VS的設計器的話這個例子的所有功能都能直接在設計器裡指定

  輸入內容(可以看到分隔符都不需要自己寫了已經寫好在輸入框裡只要填空就行)

  

  輸入內容不符合Mask屬性指定的模式時

  

  使用NumericUpDown

  C#代碼

using System;
using SystemDrawing;
using SystemWindowsForms;

  sealed class TestForm : Form
{
    private NumericUpDown m_numericUpDown;

  public TestForm() {
        InitializeComponent();
    }

  private void InitializeComponent() {
        thism_numericUpDown = new NumericUpDown();
        thism_numericUpDownValue = ;
        thism_numericUpDownDock = DockStyleFill;
        thism_numericUpDownThousandsSeparator = true;
        thism_numericUpDownMaximum = intMaxValue;

  thisClientSize = new Size( );
        thisControlsAdd(thism_numericUpDown);
        thisPerformLayout();
    }

  [SystemSTAThread]
    static void Main(string[] args) {
        ApplicationEnableVisualStyles();
        ApplicationSetCompatibleTextRenderingDefault(false);
        ApplicationRun(new TestForm());
    }
}

    這段代碼是手寫的要是用VS/VS的設計器的話這個例子的所有功能都能直接在設計器裡指定

  NumericUpDown的內容的值可以用Value屬性來設置或獲取類型為decimal

  截圖(輸入不符合要求的字符時默認行為是beep一下沒有工具條的提示)

  

  


From:http://tw.wingwit.com/Article/program/net/201311/11675.html
    推薦文章
    Copyright © 2005-2013 電腦知識網 Computer Knowledge   All rights reserved.