如何:将数据绑定到 MaskedTextBox 控件

可以将数据绑定到 MaskedTextBox 控件,就像绑定到任何其他 Windows 窗体控件一样。 但是,如果数据库中数据的格式与掩码定义所需的格式不匹配,则需要重格式化数据。 以下过程演示如何使用 Binding 类的 FormatParse 事件将单独的电话号码和电话分机数据库字段显示为单个可编辑字段。

以下过程需要具有对安装了 Northwind 示例数据库的 SQL Server 数据库的访问权限。

将数据绑定到 MaskedTextBox 控件

  1. 创建新的 Windows 窗体项目。

  2. 将两个 TextBox 控件拖到窗体上;将它们分别命名为 FirstNameLastName

  3. MaskedTextBox 控件拖到窗体上;将其命名为 PhoneMask

  4. PhoneMaskMask 属性设置为 (000) 000-0000 x9999

  5. 将以下命名空间导入添加到窗体。

    using System.Data.SqlClient;  
    
    Imports System.Data.SqlClient  
    
  6. 右键单击窗体并选择“查看代码”。 将此代码放在窗体类中的任何位置。

    Binding currentBinding, phoneBinding;  
    DataSet employeesTable = new DataSet();  
    SqlConnection sc;  
    SqlDataAdapter dataConnect;  
    
    private void Form1_Load(object sender, EventArgs e)  
    {  
        DoMaskBinding();  
    }  
    
    private void DoMaskBinding()  
    {  
        try  
        {  
            sc = new SqlConnection("Data Source=CLIENTUE;Initial Catalog=NORTHWIND;Integrated Security=SSPI");  
            sc.Open();  
        }  
        catch (Exception ex)  
        {  
            MessageBox.Show(ex.Message);  
            return;  
        }  
    
        dataConnect = new SqlDataAdapter("SELECT * FROM Employees", sc);  
        dataConnect.Fill(employeesTable, "Employees");  
    
        // Now bind MaskedTextBox to appropriate field. Note that we must create the Binding objects  
        // before adding them to the control - otherwise, we won't get a Format event on the
        // initial load.
        try  
        {  
            currentBinding = new Binding("Text", employeesTable, "Employees.FirstName");  
            firstName.DataBindings.Add(currentBinding);  
    
            currentBinding = new Binding("Text", employeesTable, "Employees.LastName");  
            lastName.DataBindings.Add(currentBinding);  
    
            phoneBinding =new Binding("Text", employeesTable, "Employees.HomePhone");  
            // We must add the event handlers before we bind, or the Format event will not get called  
            // for the first record.  
            phoneBinding.Format += new ConvertEventHandler(phoneBinding_Format);  
            phoneBinding.Parse += new ConvertEventHandler(phoneBinding_Parse);  
            phoneMask.DataBindings.Add(phoneBinding);  
        }  
        catch (Exception ex)  
        {  
            MessageBox.Show(ex.Message);  
            return;  
        }  
    }  
    
    Dim WithEvents CurrentBinding, PhoneBinding As Binding  
    Dim EmployeesTable As New DataSet()  
    Dim sc As SqlConnection  
    Dim DataConnect As SqlDataAdapter  
    
    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load  
        DoMaskedBinding()  
    End Sub  
    
    Private Sub DoMaskedBinding()  
        Try  
            sc = New SqlConnection("Data Source=SERVERNAME;Initial Catalog=NORTHWIND;Integrated Security=SSPI")  
            sc.Open()  
        Catch ex As Exception  
            MessageBox.Show(ex.Message)  
            Exit Sub  
        End Try  
    
        DataConnect = New SqlDataAdapter("SELECT * FROM Employees", sc)  
        DataConnect.Fill(EmployeesTable, "Employees")  
    
        ' Now bind MaskedTextBox to appropriate field. Note that we must create the Binding objects  
        ' before adding them to the control - otherwise, we won't get a Format event on the
        ' initial load.  
        Try  
            CurrentBinding = New Binding("Text", EmployeesTable, "Employees.FirstName")  
            firstName.DataBindings.Add(CurrentBinding)  
            CurrentBinding = New Binding("Text", EmployeesTable, "Employees.LastName")  
            lastName.DataBindings.Add(CurrentBinding)  
            PhoneBinding = New Binding("Text", EmployeesTable, "Employees.HomePhone")  
            PhoneMask.DataBindings.Add(PhoneBinding)  
        Catch ex As Exception  
            MessageBox.Show(ex.Message)  
            Application.Exit()  
        End Try  
    End Sub  
    
  7. FormatParse 事件添加事件处理程序,以将 PhoneNumberExtension 字段与绑定的 DataSet 合并和分离。

    private void phoneBinding_Format(Object sender, ConvertEventArgs e)  
    {  
        String ext;  
    
        DataRowView currentRow = (DataRowView)BindingContext[employeesTable, "Employees"].Current;  
        if (currentRow["Extension"] == null)
        {  
            ext = "";  
        } else
        {  
            ext = currentRow["Extension"].ToString();  
        }  
    
        e.Value = e.Value.ToString().Trim() + " x" + ext;  
    }  
    
    private void phoneBinding_Parse(Object sender, ConvertEventArgs e)  
    {  
        String phoneNumberAndExt = e.Value.ToString();  
    
        int extIndex = phoneNumberAndExt.IndexOf("x");  
        String ext = phoneNumberAndExt.Substring(extIndex).Trim();  
        String phoneNumber = phoneNumberAndExt.Substring(0, extIndex).Trim();  
    
        //Get the current binding object, and set the new extension manually.
        DataRowView currentRow = (DataRowView)BindingContext[employeesTable, "Employees"].Current;  
        // Remove the "x" from the extension.  
        currentRow["Extension"] = ext.Substring(1);  
    
        //Return the phone number.  
        e.Value = phoneNumber;  
    }  
    
    Private Sub PhoneBinding_Format(ByVal sender As Object, ByVal e As ConvertEventArgs) Handles PhoneBinding.Format  
        Dim Ext As String  
    
        Dim CurrentRow As DataRowView = CType(Me.BindingContext(EmployeesTable, "Employees").Current, DataRowView)  
        If (CurrentRow("Extension") Is Nothing) Then  
            Ext = ""  
        Else  
            Ext = CurrentRow("Extension").ToString()  
        End If  
    
        e.Value = e.Value.ToString().Trim() & " x" & Ext  
    End Sub  
    
    Private Sub PhoneBinding_Parse(ByVal sender As Object, ByVal e As ConvertEventArgs) Handles PhoneBinding.Parse  
        Dim PhoneNumberAndExt As String = e.Value.ToString()  
    
        Dim ExtIndex As Integer = PhoneNumberAndExt.IndexOf("x")  
        Dim Ext As String = PhoneNumberAndExt.Substring(ExtIndex).Trim()  
        Dim PhoneNumber As String = PhoneNumberAndExt.Substring(0, ExtIndex).Trim()  
    
        ' Get the current binding object, and set the new extension manually.
        Dim CurrentRow As DataRowView = CType(Me.BindingContext(EmployeesTable, "Employees").Current, DataRowView)  
        ' Remove the "x" from the extension.  
        CurrentRow("Extension") = CObj(Ext.Substring(1))  
    
        ' Return the phone number.  
        e.Value = PhoneNumber  
    End Sub  
    
  8. 向窗体添加两个 Button 控件。 将它们分别命名为 previousButtonnextButton。 双击每个按钮以添加 Click 事件处理程序,并填充事件处理程序,如以下代码示例所示。

    private void previousButton_Click(object sender, EventArgs e)  
    {  
        BindingContext[employeesTable, "Employees"].Position = BindingContext[employeesTable, "Employees"].Position - 1;  
    }  
    
    private void nextButton_Click(object sender, EventArgs e)  
    {  
        BindingContext[employeesTable, "Employees"].Position = BindingContext[employeesTable, "Employees"].Position + 1;  
    }  
    
    Private Sub PreviousButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PreviousButton.Click  
        Me.BindingContext(EmployeesTable, "Employees").Position = Me.BindingContext(EmployeesTable, "Employees").Position - 1  
    End Sub  
    
    Private Sub NextButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NextButton.Click  
        Me.BindingContext(EmployeesTable, "Employees").Position = Me.BindingContext(EmployeesTable, "Employees").Position + 1  
    End Sub  
    
  9. 运行该示例。 编辑数据,然后使用“上一个”和“下一个”按钮查看数据是否正确永久保存到 DataSet

示例

以下代码示例是在完成上一过程后得到的完整代码列表。

#pragma region Using directives

#using <System.dll>
#using <System.Data.dll>
#using <System.Drawing.dll>
#using <System.Windows.Forms.dll>
#using <System.Xml.dll>
#using <System.EnterpriseServices.dll>
#using <System.Transactions.dll>

using namespace System;
using namespace System::Collections::Generic;
using namespace System::ComponentModel;
using namespace System::Data;
using namespace System::Drawing;
using namespace System::Windows::Forms;
using namespace System::Data::SqlClient;

#pragma endregion

namespace MaskedTextBoxDataCSharp
{
    public ref class Form1 : public Form
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
    private:
        System::ComponentModel::IContainer^ components;

    public:
        Form1()
        {
            InitializeComponent();
        }

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
    protected:
        ~Form1()
        {
            if (components != nullptr)
            {
                delete components;
            }
        }



#pragma region Windows Form Designer generated code

               /// <summary>
               /// Required method for Designer support - do not modify
               /// the contents of this method with the code editor.
               /// </summary>
    private:
        void InitializeComponent()
        {
            employeesTable = gcnew DataSet();
            components = nullptr;
            this->firstName = gcnew System::Windows::Forms::TextBox();
            this->lastName = gcnew System::Windows::Forms::TextBox();
            this->phoneMask = gcnew System::Windows::Forms::MaskedTextBox();
            this->previousButton = gcnew System::Windows::Forms::Button();
            this->nextButton = gcnew System::Windows::Forms::Button();
            this->SuspendLayout();
            //
            // firstName
            //
            this->firstName->Location = System::Drawing::Point(13, 14);
            this->firstName->Name = "firstName";
            this->firstName->Size = System::Drawing::Size(184, 20);
            this->firstName->TabIndex = 0;
            //
            // lastName
            //
            this->lastName->Location = System::Drawing::Point(204, 14);
            this->lastName->Name = "lastName";
            this->lastName->Size = System::Drawing::Size(184, 20);
            this->lastName->TabIndex = 1;
            //
            // phoneMask
            //
            this->phoneMask->Location = System::Drawing::Point(441, 14);
            this->phoneMask->Mask = "(009) 000-0000 x9999";
            this->phoneMask->Name = "phoneMask";
            this->phoneMask->Size = System::Drawing::Size(169, 20);
            this->phoneMask->TabIndex = 2;
            //
            // previousButton
            //
            this->previousButton->Location = System::Drawing::Point(630, 14);
            this->previousButton->Name = "previousButton";
            this->previousButton->TabIndex = 3;
            this->previousButton->Text = "Previous";
            this->previousButton->Click += gcnew System::EventHandler(this,&Form1::previousButton_Click);
            //
            // nextButton
            //
            this->nextButton->Location = System::Drawing::Point(723, 14);
            this->nextButton->Name = "nextButton";
            this->nextButton->TabIndex = 4;
            this->nextButton->Text = "Next";
            this->nextButton->Click += gcnew System::EventHandler(this,&Form1::nextButton_Click);
            //
            // Form1
            //
            this->AutoScaleBaseSize = System::Drawing::Size(5, 13);
            this->ClientSize = System::Drawing::Size(887, 46);
            this->Controls->Add(this->nextButton);
            this->Controls->Add(this->previousButton);
            this->Controls->Add(this->phoneMask);
            this->Controls->Add(this->lastName);
            this->Controls->Add(this->firstName);
            this->Name = "Form1";
            this->Text = "Form1";
            this->Load += gcnew System::EventHandler(this,&Form1::Form1_Load);
            this->ResumeLayout(false);
            this->PerformLayout();
        }

#pragma endregion

    private:
        System::Windows::Forms::TextBox^ firstName;
        System::Windows::Forms::TextBox^ lastName;
        System::Windows::Forms::MaskedTextBox^ phoneMask;
        System::Windows::Forms::Button^ previousButton;
        System::Windows::Forms::Button^ nextButton;

    private:
        Binding^ currentBinding;
        Binding^ phoneBinding;
        DataSet^ employeesTable;
        SqlConnection^ sc;
        SqlDataAdapter^ dataConnect;

    private:
        void Form1_Load(Object^ sender, EventArgs^ e)
        {
            DoMaskBinding();
        }

    private:
        void DoMaskBinding()
        {
            try
            {
                sc = gcnew SqlConnection("Data Source=localhost;" +
                    "Initial Catalog=NORTHWIND;Integrated Security=SSPI");
                sc->Open();
            }
            catch (Exception^ ex)
            {
                MessageBox::Show(ex->Message);
                return;
            }

            dataConnect = gcnew SqlDataAdapter("SELECT * FROM Employees", sc);
            dataConnect->Fill(employeesTable, "Employees");


            // Now bind MaskedTextBox to appropriate field. Note that we must
            // create the Binding objects before adding them to the control -
            // otherwise, we won't get a Format event on the initial load.
            try
            {
                currentBinding = gcnew Binding("Text", employeesTable,
                    "Employees.FirstName");
                firstName->DataBindings->Add(currentBinding);

                currentBinding = gcnew Binding("Text", employeesTable,
                    "Employees.LastName");
                lastName->DataBindings->Add(currentBinding);

                phoneBinding = gcnew Binding("Text", employeesTable, 
                    "Employees.HomePhone");
                // We must add the event handlers before we bind, or the
                // Format event will not get called for the first record.
                phoneBinding->Format += gcnew
                    ConvertEventHandler(this, &Form1::phoneBinding_Format);
                phoneBinding->Parse += gcnew
                    ConvertEventHandler(this, &Form1::phoneBinding_Parse);
                phoneMask->DataBindings->Add(phoneBinding);
            }
            catch (Exception^ ex)
            {
                MessageBox::Show(ex->Message);
                return;
            }
        }

    private:
        void phoneBinding_Format(Object^ sender, ConvertEventArgs^ e)
        {
            String^ ext;

            DataRowView^ currentRow = (DataRowView^) BindingContext[
                employeesTable, "Employees"]->Current;
                if (currentRow["Extension"] == nullptr)
                {
                    ext = "";
                }
                else
                {
                    ext = currentRow["Extension"]->ToString();
                }

                e->Value = e->Value->ToString()->Trim() + " x" + ext;
        }

    private:
        void phoneBinding_Parse(Object^ sender, ConvertEventArgs^ e)
        {
            String^ phoneNumberAndExt = e->Value->ToString();

            int extIndex = phoneNumberAndExt->IndexOf("x");
            String^ ext = phoneNumberAndExt->Substring(extIndex)->Trim();
            String^ phoneNumber = 
                phoneNumberAndExt->Substring(0, extIndex)->Trim();

            //Get the current binding object, and set the new extension 
            //manually.
            DataRowView^ currentRow = 
                (DataRowView^ ) BindingContext[employeesTable,
                "Employees"]->Current;
            // Remove the "x" from the extension.
            currentRow["Extension"] = ext->Substring(1);

            //Return the phone number.
            e->Value = phoneNumber;
        }

    private:
        void previousButton_Click(Object^ sender, EventArgs^ e)
        {
            BindingContext[employeesTable, "Employees"]->Position =
                BindingContext[employeesTable, "Employees"]->Position - 1;
        }

    private:
        void nextButton_Click(Object^ sender, EventArgs^ e)
        {
            BindingContext[employeesTable, "Employees"]->Position =
                BindingContext[employeesTable, "Employees"]->Position + 1;
        }
    };
}

[STAThread]
int main()
{
    Application::EnableVisualStyles();
    Application::Run(gcnew MaskedTextBoxDataCSharp::Form1());
}
#region Using directives

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Windows.Forms;
using System.Data.SqlClient;

#endregion

namespace MaskedTextBoxDataCSharp
{
    partial class Form1 : Form
    {
        Binding currentBinding, phoneBinding;
        DataSet employeesTable = new DataSet();
        SqlConnection sc;
        SqlDataAdapter dataConnect;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            DoMaskBinding();
        }

        private void DoMaskBinding()
        {
            try
            {
                sc = new SqlConnection("Data Source=localhost;Initial Catalog=NORTHWIND;Integrated Security=SSPI");
                sc.Open();
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }

            dataConnect = new SqlDataAdapter("SELECT * FROM Employees", sc);
            dataConnect.Fill(employeesTable, "Employees");

            // Now bind MaskedTextBox to appropriate field. Note that we must create the Binding objects
            // before adding them to the control - otherwise, we won't get a Format event on the
            // initial load.
            try
            {
                currentBinding = new Binding("Text", employeesTable, "Employees.FirstName");
                firstName.DataBindings.Add(currentBinding);

                currentBinding = new Binding("Text", employeesTable, "Employees.LastName");
                lastName.DataBindings.Add(currentBinding);

                phoneBinding =new Binding("Text", employeesTable, "Employees.HomePhone");
                // We must add the event handlers before we bind, or the Format event will not get called
                // for the first record.
                phoneBinding.Format += new ConvertEventHandler(phoneBinding_Format);
                phoneBinding.Parse += new ConvertEventHandler(phoneBinding_Parse);
                phoneMask.DataBindings.Add(phoneBinding);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
                return;
            }
        }

        private void phoneBinding_Format(Object sender, ConvertEventArgs e)
        {
            String ext;

            DataRowView currentRow = (DataRowView)BindingContext[employeesTable, "Employees"].Current;
            if (currentRow["Extension"] == null)
            {
                ext = "";
            } else
            {
                ext = currentRow["Extension"].ToString();
            }

            e.Value = e.Value.ToString().Trim() + " x" + ext;
        }

        private void phoneBinding_Parse(Object sender, ConvertEventArgs e)
        {
            String phoneNumberAndExt = e.Value.ToString();

            int extIndex = phoneNumberAndExt.IndexOf("x");
            String ext = phoneNumberAndExt.Substring(extIndex).Trim();
            String phoneNumber = phoneNumberAndExt.Substring(0, extIndex).Trim();

            //Get the current binding object, and set the new extension manually.
            DataRowView currentRow = (DataRowView)BindingContext[employeesTable, "Employees"].Current;
            // Remove the "x" from the extension.
            currentRow["Extension"] = ext.Substring(1);

            //Return the phone number.
            e.Value = phoneNumber;
        }

        private void previousButton_Click(object sender, EventArgs e)
        {
            BindingContext[employeesTable, "Employees"].Position = BindingContext[employeesTable, "Employees"].Position - 1;
        }

        private void nextButton_Click(object sender, EventArgs e)
        {
            BindingContext[employeesTable, "Employees"].Position = BindingContext[employeesTable, "Employees"].Position + 1;
        }
    }
}
Imports System.Data.SqlClient

Public Class Form1
    Dim WithEvents CurrentBinding, PhoneBinding As Binding
    Dim EmployeesTable As New DataSet()
    Dim sc As SqlConnection
    Dim DataConnect As SqlDataAdapter

    Private Sub Form1_Load(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles MyBase.Load
        DoMaskedBinding()
    End Sub

    Private Sub DoMaskedBinding()
        Try
            sc = New SqlConnection("Data Source=localhost;Initial Catalog=NORTHWIND;Integrated Security=SSPI")
            sc.Open()
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Application.Exit()
        End Try

        DataConnect = New SqlDataAdapter("SELECT * FROM Employees", sc)
        DataConnect.Fill(EmployeesTable, "Employees")

        ' Now bind MaskedTextBox to appropriate field. Note that we must create the Binding objects
        ' before adding them to the control - otherwise, we won't get a Format event on the 
        ' initial load. 
        Try
            CurrentBinding = New Binding("Text", EmployeesTable, "Employees.FirstName")
            firstName.DataBindings.Add(CurrentBinding)
            CurrentBinding = New Binding("Text", EmployeesTable, "Employees.LastName")
            lastName.DataBindings.Add(CurrentBinding)
            PhoneBinding = New Binding("Text", EmployeesTable, "Employees.HomePhone")
            PhoneMask.DataBindings.Add(PhoneBinding)
        Catch ex As Exception
            MessageBox.Show(ex.Message)
            Application.Exit()
        End Try
    End Sub

    Private Sub PhoneBinding_Format(ByVal sender As Object, ByVal e As ConvertEventArgs) Handles PhoneBinding.Format
        Dim Ext As String

        Dim CurrentRow As DataRowView = CType(Me.BindingContext(EmployeesTable, "Employees").Current, DataRowView)
        If (CurrentRow("Extension") Is Nothing) Then
            Ext = ""
        Else
            Ext = CurrentRow("Extension").ToString()
        End If

        e.Value = e.Value.ToString().Trim() & " x" & Ext
    End Sub

    Private Sub PhoneBinding_Parse(ByVal sender As Object, ByVal e As ConvertEventArgs) Handles PhoneBinding.Parse
        Dim PhoneNumberAndExt As String = e.Value.ToString()

        Dim ExtIndex As Integer = PhoneNumberAndExt.IndexOf("x")
        Dim Ext As String = PhoneNumberAndExt.Substring(ExtIndex).Trim()
        Dim PhoneNumber As String = PhoneNumberAndExt.Substring(0, ExtIndex).Trim()

        ' Get the current binding object, and set the new extension manually. 
        Dim CurrentRow As DataRowView = CType(Me.BindingContext(EmployeesTable, "Employees").Current, DataRowView)
        ' Remove the "x" from the extension.
        CurrentRow("Extension") = CObj(Ext.Substring(1))

        ' Return the phone number.
        e.Value = PhoneNumber
    End Sub

    Private Sub NextButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles NextButton.Click
        Me.BindingContext(EmployeesTable, "Employees").Position = Me.BindingContext(EmployeesTable, "Employees").Position + 1
    End Sub

    Private Sub PreviousButton_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PreviousButton.Click
        Me.BindingContext(EmployeesTable, "Employees").Position = Me.BindingContext(EmployeesTable, "Employees").Position - 1
    End Sub
End Class

编译代码

  • 创建 Visual C# 或 Visual Basic 项目。

  • TextBoxMaskedTextBox 控件添加到窗体中,如上一过程中所述。

  • 打开项目的默认窗体的源代码文件。

  • 将此文件中的源代码替换为前面“代码”部分中列出的代码。

  • 编译该应用程序。

另请参阅