다음을 통해 공유


방법: 데이터 바인딩에서 발생하는 오류 및 예외 처리

업데이트: 2007년 11월

컨트롤에 내부 비즈니스 개체를 바인딩하면 예외와 오류가 발생하는 경우가 종종 있습니다. 특정 Binding, BindingSource 또는 CurrencyManager 구성 요소에 대해 BindingComplete 이벤트를 처리하여 이러한 오류와 예외를 차단한 다음 오류를 복구하거나 오류 정보를 사용자에게 보낼 수 있습니다.

예제

이 코드 예제에서는 데이터 바인딩 작업을 하는 동안 발생하는 오류와 예외를 처리하는 방법을 보여 줍니다. 또한 Binding 개체의 Binding.BindingComplete 이벤트를 처리하여 오류를 차단하는 방법도 보여 줍니다. 이 이벤트를 처리하여 오류와 예외를 차단하려면 바인딩에 서식을 지정할 수 있는 기능을 사용해야 합니다. 바인딩이 생성되거나 바인딩 컬렉션에 바인딩이 추가될 때 서식 지정 기능을 사용하도록 설정하거나 FormattingEnabled 속성을 true로 설정하면 됩니다.

Imports System
Imports System.Drawing
Imports System.Windows.Forms

Class Form1
    Inherits Form

    Private  BindingSource1 As New BindingSource()
    Private textBox1 As New TextBox()
    Private textBox2 As New TextBox()
    Private textBox3 As New TextBox()

    Public Sub New()

        'Set up the textbox controls.
        Me.textBox1.Location = New System.Drawing.Point(82, 13)
        Me.textBox1.TabIndex = 1
        Me.textBox2.Location = New System.Drawing.Point(81, 47)
        Me.textBox2.TabIndex = 2
        Me.textBox3.Location = New System.Drawing.Point(81, 83)
        Me.textBox3.TabIndex = 3

        ' Add the textbox controls to the form
        Me.Controls.Add(Me.textBox2)
        Me.Controls.Add(Me.textBox1)
        Me.Controls.Add(Me.textBox3)

    End Sub

    Private WithEvents partNameBinding As Binding
    Private WithEvents partNumberBinding As Binding

    Private Sub Form1_Load(ByVal sender As Object, ByVal e As EventArgs) _
        Handles Me.Load

        ' Set the DataSource of BindingSource1 to the Part type.
        BindingSource1.DataSource = GetType(Part)

        ' Bind the textboxes to the properties of the Part type, 
        ' enabling formatting.
        partNameBinding = textBox1.DataBindings.Add("Text", BindingSource1, _
            "PartName", True)
        partNumberBinding = textBox2.DataBindings.Add("Text", BindingSource1, _
            "PartNumber", True)

        'Bind the textbox to the PartPrice value with currency formatting.
        textBox3.DataBindings.Add("Text", BindingSource1, "PartPrice", _
            True, DataSourceUpdateMode.OnPropertyChanged, 0, "C")

        ' Add a new part to BindingSource1.
        BindingSource1.Add(New Part("Widget", 1234, 12.45))
    End Sub

    ' Handle the BindingComplete event to catch errors and exceptions 
    ' in binding process.
    Sub partNumberBinding_BindingComplete(ByVal sender As Object, _
        ByVal e As BindingCompleteEventArgs) _
        Handles partNumberBinding.BindingComplete

        If Not e.BindingCompleteState = BindingCompleteState.Success Then
            MessageBox.Show("partNumberBinding: " + e.ErrorText)
        End If

    End Sub

    ' Handle the BindingComplete event to catch errors and exceptions 
    ' in binding process.
    Sub partNameBinding_BindingComplete(ByVal sender As Object, _
        ByVal e As BindingCompleteEventArgs) _
        Handles partNameBinding.BindingComplete

        If Not e.BindingCompleteState = BindingCompleteState.Success Then
            MessageBox.Show("partNameBinding: " + e.ErrorText)
        End If

    End Sub

    <STAThread()> _
    Shared Sub Main()
        Application.EnableVisualStyles()
        Application.Run(New Form1())
    End Sub

End Class

' Represents a business object that throws exceptions when invalid 
' values are entered for some of its properties.
Public Class Part
    Private name As String
    Private number As Integer
    Private price As Double

    Public Sub New(ByVal name As String, ByVal number As Integer, _
        ByVal price As Double)

        PartName = name
        PartNumber = number
        PartPrice = price
    End Sub


    Public Property PartName() As String
        Get
            Return name
        End Get
        Set(ByVal value As String)
            If Value.Length <= 0 Then
                Throw New Exception("Each part must have a name.")
            Else
                name = Value
            End If
        End Set
    End Property

    Public Property PartPrice() As Double
        Get
            Return price
        End Get
        Set(ByVal value As Double)
            price = Value
        End Set
    End Property

    Public Property PartNumber() As Integer
        Get
            Return number
        End Get
        Set(ByVal value As Integer)
            If Value < 100 Then
                Throw New Exception("Invalid part number." _
                    & " Part numbers must be greater than 100.")
            Else
                number = Value
            End If
        End Set
    End Property
End Class
using System;
using System.Drawing;
using System.Windows.Forms;

class Form1 : Form
{
    private BindingSource BindingSource1 = new BindingSource();
    private TextBox textBox1 = new TextBox();
    private TextBox textBox2 = new TextBox();
    private TextBox textBox3 = new TextBox();

    public Form1()
    {
        //Set up the textbox controls.
        this.textBox1.Location = new System.Drawing.Point(82, 13);
        this.textBox1.TabIndex = 1;
        this.textBox2.Location = new System.Drawing.Point(81, 47);
        this.textBox2.TabIndex = 2;
        this.textBox3.Location = new System.Drawing.Point(81, 83);
        this.textBox3.TabIndex = 3;

        // Add the textbox controls to the form
        this.Controls.Add(this.textBox2);
        this.Controls.Add(this.textBox1);
        this.Controls.Add(this.textBox3);

        // Handle the form's Load event.
        this.Load += new System.EventHandler(this.Form1_Load);
    }
    Binding partNameBinding;
    Binding partNumberBinding;

    private void Form1_Load(object sender, EventArgs e)
    {
        // Set the DataSource of BindingSource1 to the Part type.
        BindingSource1.DataSource = typeof(Part);

        // Bind the textboxes to the properties of the Part type, 
        // enabling formatting.
        partNameBinding = textBox1.DataBindings.Add("Text",
            BindingSource1, "PartName", true);
        
        partNumberBinding = textBox2.DataBindings.Add("Text", BindingSource1, "PartNumber",
            true);

        //Bind the textbox to the PartPrice value with currency formatting.
        textBox3.DataBindings.Add("Text", BindingSource1, "PartPrice", true,
            DataSourceUpdateMode.OnPropertyChanged, 0, "C");
            

        // Handle the BindingComplete event for BindingSource1 and 
        // the partNameBinding.
        partNumberBinding.BindingComplete +=
            new BindingCompleteEventHandler(partNumberBinding_BindingComplete);
        partNameBinding.BindingComplete +=
            new BindingCompleteEventHandler(partNameBinding_BindingComplete);

        // Add a new part to BindingSource1.
        BindingSource1.Add(new Part("Widget", 1234, 12.45));
    }

    // Handle the BindingComplete event to catch errors and exceptions 
    // in binding process.
    void partNumberBinding_BindingComplete(object sender,
        BindingCompleteEventArgs e)
    {
        if (e.BindingCompleteState != BindingCompleteState.Success)
            MessageBox.Show("partNumberBinding: " + e.ErrorText);
    }       

    // Handle the BindingComplete event to catch errors and 
    // exceptions in binding process.
    void partNameBinding_BindingComplete(object sender,
        BindingCompleteEventArgs e)
    {
        if (e.BindingCompleteState != BindingCompleteState.Success)
            MessageBox.Show("partNameBinding: " + e.ErrorText);
    }

    [STAThread]
    static void Main()
    {
        Application.EnableVisualStyles();
        Application.Run(new Form1());
    }
}

// Represents a business object that throws exceptions when invalid values are
// entered for some of its properties.
public class Part
{
    private string name;
    private int number;
    private double price;

    public Part(string name, int number, double price)
    {
        PartName = name;
        PartNumber = number;
        PartPrice = price;
    }

    public string PartName
    {
        get { return name; }
        set
        {
            if (value.Length <= 0)
                throw new Exception("Each part must have a name.");
            else
                name = value;
        }
    }
    public double PartPrice
    {
        get { return price; }
        set { price = value; }
    }

    public int PartNumber
    {
        get { return number; }
        set
        {
            if (value < 100)
                throw new Exception("Invalid part number." +
                    " Part numbers must be greater than 100.");
            else
                number = value;
        }
    }
}
// Represents a business object that throws exceptions when 
// invalid values are entered for some of its properties.
public ref class Part
{
private:
    String^ name;
    int number;
    double price;

public:
    Part(String^ name, int number, double price)
    {
        PartName = name;
        PartNumber = number;
        PartPrice = price;
    }

    property String^ PartName 
    {
        String^ get()
        {
            return name;
        }

        void set(String^ value)
        {
            if (value->Length <= 0)
            {
                throw gcnew Exception(
                    "Each part must have a name.");
            }
            else
            {
                name = value;
            }
        }
    }

    property double PartPrice 
    {
        double get()
        {
            return price;
        }

        void set(double value)
        {
            price = value;
        }
    }

    property int PartNumber 
    {
        int get()
        {
            return number;
        }

        void set(int value)
        {
            if (value < 100)
            {
                throw gcnew Exception(
                    "Invalid part number." \
                    "Part numbers must be " \
                    "greater than 100.");
            }
            else
            {
                number = value;
            }
        }
    }

};

ref class MainForm: public Form
{
private:
    BindingSource^ bindingSource;
    TextBox^ partNameTextBox;
    TextBox^ partNumberTextBox;
    TextBox^ partPriceTextBox;

public:
    MainForm()
    {
        bindingSource = gcnew BindingSource;
        partNameTextBox = gcnew TextBox;
        partNumberTextBox = gcnew TextBox;
        partPriceTextBox = gcnew TextBox;

        //Set up the textbox controls.
        this->partNameTextBox->Location = Point(82, 13);
        this->partNameTextBox->TabIndex = 1;
        this->partNumberTextBox->Location = Point(81, 47);
        this->partNumberTextBox->TabIndex = 2;
        this->partPriceTextBox->Location = Point(81, 83);
        this->partPriceTextBox->TabIndex = 3;

        // Add the textbox controls to the form
        this->Controls->Add(this->partNumberTextBox);
        this->Controls->Add(this->partNameTextBox);
        this->Controls->Add(this->partPriceTextBox);

        // Handle the form's Load event.
        this->Load += gcnew EventHandler(this, 
            &MainForm::OnMainFormLoad);
    }

private:

    void OnMainFormLoad(Object^ sender, EventArgs^ e)
    {   
        // Set the DataSource of bindingSource to the Part type.
        bindingSource->DataSource = Part::typeid;

        // Bind the textboxes to the properties of the Part type,
        // enabling formatting.
        partNameTextBox->DataBindings->Add(
            "Text", bindingSource, "PartName", true);
        partNumberTextBox->DataBindings->Add(
            "Text", bindingSource, "PartNumber", true);

        //Bind the textbox to the PartPrice value 
        // with currency formatting.
        partPriceTextBox->DataBindings->Add("Text", bindingSource, "PartPrice", true,
           DataSourceUpdateMode::OnPropertyChanged, nullptr, "C");

        // Handle the BindingComplete event for bindingSource and
        // the partNameBinding.
        bindingSource->BindingComplete += 
            gcnew BindingCompleteEventHandler(this, 
            &MainForm::OnBindingSourceBindingComplete);
        bindingSource->BindingComplete += 
            gcnew BindingCompleteEventHandler(this, 
            &MainForm::OnPartNameBindingBindingComplete);

        // Add a new part to bindingSource.
        bindingSource->Add(gcnew Part("Widget", 1234, 12.45));
    }

    // Handle the BindingComplete event to catch errors and 
    // exceptions in binding process.
    void OnBindingSourceBindingComplete(Object^ sender, 
        BindingCompleteEventArgs^ e)
    {
        if (e->BindingCompleteState == 
            BindingCompleteState::Exception)
        {
            MessageBox::Show(String::Format(
                CultureInfo::CurrentCulture,
                "bindingSource: {0}", e->Exception->Message));
        }

        if (e->BindingCompleteState == 
            BindingCompleteState::DataError)
        {
            MessageBox::Show(String::Format(
                CultureInfo::CurrentCulture,
                "bindingSource: {0}", e->Exception->Message));
        }
    }

    // Handle the BindingComplete event to catch errors and 
    // exceptions in binding process.
    void OnPartNameBindingBindingComplete(Object^ sender, 
        BindingCompleteEventArgs^ e)
    {
        if (e->BindingCompleteState == 
            BindingCompleteState::Exception)
        {
            MessageBox::Show(String::Format(
                CultureInfo::CurrentCulture,
                "PartNameBinding: {0}", e->Exception->Message));
        }

        if (e->BindingCompleteState == 
            BindingCompleteState::DataError)
        {
            MessageBox::Show(String::Format(
                CultureInfo::CurrentCulture,
                "PartNameBinding: {0}", e->Exception->Message));
        }
    }
};

코드를 실행할 때 이름의 일부로 빈 문자열이 입력되거나 100보다 작은 값이 입력되면 메시지 상자가 표시됩니다. 이러한 텍스트 상자 바인딩에 대해 Binding.BindingComplete 이벤트를 처리하여 발생하는 결과입니다.

코드 컴파일

이 예제에는 다음 사항이 필요합니다.

  • System, System.Drawing 및 System.Windows.Forms 어셈블리에 대한 참조

Visual Basic 또는 Visual C#의 명령줄에서 이 예제를 빌드하는 방법에 대한 자세한 내용은 명령줄에서 빌드(Visual Basic) 또는 csc.exe를 사용한 명령줄 빌드를 참조하십시오. Visual Studio에서 코드를 새 프로젝트에 붙여넣어 이 예제를 빌드할 수도 있습니다.

참고 항목

참조

Binding.BindingComplete

BindingSource.BindingComplete

기타 리소스

BindingSource 구성 요소