Поделиться через


Практическое руководство. Связывание данных с элементом управления MaskedTextBox

Данные можно привязать к элементу управления MaskedTextBox так же, как к любому другому элементу управления Windows Forms. Однако если формат данных в базе данных не соответствует формату, ожидаемому определением маски, необходимо будет переформатировать данные. В следующей процедуре показано, как это сделать с помощью событий Format и Parse класса Binding для отображения отдельных полей базы данных с номером телефона и добавочным номером в виде одного редактируемого поля.

Для выполнения следующей процедуры требуется доступ к базе данных SQL Server с установленным примером базы данных Northwind.

Связывание данных с элементом управления MaskedTextBox

  1. Создайте проект Windows Forms.

  2. Перетащите два элемента управления TextBox в форму; присвойте им имя FirstName и LastName.

  3. Перетащите элемент управления MaskedTextBox в форму и присвойте ему имя PhoneMask.

  4. Задайте для свойства MaskPhoneMask значение (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. Добавьте обработчики событий для событий Format и Parse, чтобы объединить и отделить поля PhoneNumber и Extension от границы 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. Присвойте им имена previousButton и nextButton. Дважды щелкните каждую кнопку, чтобы добавить обработчик событий 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.

  • Добавьте элементы управления TextBox и MaskedTextBox в форму, как описано в предыдущей процедуре.

  • Откройте файл исходного кода для формы проекта по умолчанию.

  • Замените исходный код в этом файле кодом, указанным в предыдущем разделе "Код".

  • Скомпилируйте приложение.

См. также