다음을 통해 공유


바인딩 선언이란? (WPF .NET)

일반적으로 개발자는 데이터를 바인딩하려는 UI 요소의 XAML 태그에서 직접 바인딩을 선언합니다. 하지만 코드에서 바인딩을 선언할 수도 있습니다. 이 문서에서는 XAML과 코드에서 바인딩을 선언하는 방법을 설명합니다.

필수 구성 요소

이 문서를 읽기 전에 태그 확장의 개념과 사용에 대해 잘 알고 있는 것이 중요합니다. 태그 확장에 대한 자세한 내용은 XAML 태그 확장 및 WPF XAML을 참조하세요.

이 문서에서는 데이터 바인딩 개념을 다루지 않습니다. 데이터 바인딩 개념에 대한 자세한 내용은 데이터 바인딩 개요를 참조하세요.

XAML에서 바인딩 선언

Binding은 태그 확장입니다. 바인딩 확장을 사용하여 바인딩을 선언할 때 선언은 Binding 키워드 뒤에 일련의 절이 쉼표(,)로 구분된 형태로 구성됩니다. 바인딩 선언의 절 순서는 중요하지 않으며 수많은 조합이 가능합니다. 절은 Name=Value 쌍입니다. 여기서 NameBinding 속성의 이름이고 Value는 속성에 설정하는 값입니다.

태그에서 바인딩 선언 문자열을 만들 때는 대상 개체의 특정 종속성 속성에 연결해야 합니다. 다음 예제는 바인딩 확장을 사용하여 TextBox.Text 속성을 바인딩하고 SourcePath 속성을 지정하는 방법을 보여 줍니다.

<TextBlock Text="{Binding Source={StaticResource myDataSource}, Path=Name}"/>

이전 예제는 Person의 간단한 데이터 개체 형식을 사용합니다. 다음 코드 조각은 해당 개체의 코드입니다.

class Person
{
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
}
Public Class Person

    Public Property Name As String
    Public Property Birthdate As DateTime
    
End Class

이 방법으로 Binding 클래스의 속성 대부분을 지정할 수 있습니다. 바인딩 확장에 대한 정보와 바인딩 확장을 사용하여 설정할 수 없는 Binding 속성의 목록은 바인딩 태그 확장(.NET Framework) 개요를 참조하세요.

XAML에서 바인딩을 만드는 방법에 대한 예는 데이터 바인딩을 만드는 방법을 참조하세요.

개체 요소 구문

개체 요소 구문은 바인딩 선언을 만드는 대신 사용할 수 있습니다. 대부분의 경우 태그 확장 또는 개체 요소 구문을 사용할 때의 특별한 이점은 없습니다. 그러나 태그 확장을 사용할 수 없는 시나리오, 예를 들어 속성 값이 문자열 형식이 아니어서 형식 변환이 존재하지 않는 경우에는 개체 요소 구문을 사용해야 합니다.

이전 섹션에서는 XAML 확장에 바인딩하는 방법을 설명했습니다. 다음 예제는 동일한 바인딩을 수행하지만 개체 요소 구문을 사용하는 것을 보여 줍니다.

<TextBlock>
    <TextBlock.Text>
        <Binding Source="{StaticResource myDataSource}" Path="Name"/>
    </TextBlock.Text>
</TextBlock>

다양한 용어에 대한 자세한 내용은 XAML 구문 정보(.NET Framework)를 참조하세요.

MultiBinding 및 PriorityBinding

MultiBindingPriorityBinding은 XAML 확장 구문을 지원하지 않습니다. 따라서 XAML에서 MultiBinding 또는 PriorityBinding을 선언하는 경우 개체 요소 구문을 사용해야 합니다.

코드로 바인딩 만들기

바인딩을 지정하는 또 다른 방법은 코드에서 직접 Binding 개체에 속성을 설정한 다음 속성에 바인딩을 할당하는 것입니다. 다음 예제는 코드에서 Binding 개체를 만드는 방법을 보여 줍니다.

private void Window_Loaded(object sender, RoutedEventArgs e)
{
    // Make a new data source object
    var personDetails = new Person()
    {
        Name = "John",
        Birthdate = DateTime.Parse("2001-02-03")
    };

    // New binding object using the path of 'Name' for whatever source object is used
    var nameBindingObject = new Binding("Name");

    // Configure the binding
    nameBindingObject.Mode = BindingMode.OneWay;
    nameBindingObject.Source = personDetails;
    nameBindingObject.Converter = NameConverter.Instance;
    nameBindingObject.ConverterCulture = new CultureInfo("en-US");

    // Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
    BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject);
}
Private Sub Window_Loaded(sender As Object, e As RoutedEventArgs)

    ' Make a new data source object
    Dim personDetails As New Person() With {
        .Name = "John",
        .Birthdate = Date.Parse("2001-02-03")
    }

    ' New binding object using the path of 'Name' for whatever source object is used
    Dim nameBindingObject As New Binding("Name")

    ' Configure the binding
    nameBindingObject.Mode = BindingMode.OneWay
    nameBindingObject.Source = personDetails
    nameBindingObject.Converter = NameConverter.Instance
    nameBindingObject.ConverterCulture = New CultureInfo("en-US")

    ' Set the binding to a target object. The TextBlock.Name property on the NameBlock UI element
    BindingOperations.SetBinding(NameBlock, TextBlock.TextProperty, nameBindingObject)

End Sub

이전 코드는 바인딩에서 다음을 설정했습니다.

  • 데이터 원본 개체에서 속성의 경로
  • 바인딩 모드
  • 데이터 원본(이 경우 사람을 나타내는 단순 개체 인스턴스)
  • 대상 속성에 할당되기 전에 데이터 원본 개체에서 들어오는 값을 처리하는 선택적 변환기

바인딩하는 개체가 FrameworkElement 또는 FrameworkContentElement인 경우 BindingOperations.SetBinding를 사용하는 대신 개체에서 직접 SetBinding을 호출할 수 있습니다. 예제는 방법: 코드에서 바인딩 만들기를 참조하세요.

이전 예제는 Person의 간단한 데이터 개체 형식을 사용합니다. 다음은 해당 개체의 코드입니다.

class Person
{
    public string Name { get; set; }
    public DateTime Birthdate { get; set; }
}
Public Class Person

    Public Property Name As String
    Public Property Birthdate As DateTime
    
End Class

바인딩 경로 구문

Path 속성을 사용하여 바인딩할 원본 값을 지정합니다.

  • 가장 간단한 경우는 Path 속성 값이 Path=PropertyName과 같이 바인딩에 사용할 원본 개체의 속성 이름인 경우입니다.

  • C#에서처럼 비슷한 구문으로 속성의 하위 속성을 지정할 수 있습니다. 예를 들어 Path=ShoppingCart.Order 절은 개체 또는 속성 ShoppingCart의 하위 속성 Order에 대한 바인딩을 설정합니다.

  • 연결된 속성에 바인딩하려면 연결된 속성을 괄호로 묶습니다. 예를 들어 연결된 속성 DockPanel.Dock에 바인딩하려면 구문은 Path=(DockPanel.Dock)입니다.

  • 속성의 인덱서는 인덱서가 적용되는 속성 이름 뒤에 대괄호로 묶어서 지정할 수 있습니다. 예를 들어 Path=ShoppingCart[0] 절은 속성의 내부 인덱싱에서 리터럴 문자열 "0"을 처리하는 방법에 해당하는 인덱스에 대한 바인딩을 설정합니다. 중첩된 인덱서도 지원됩니다.

  • Path=ShoppingCart.ShippingInfo[MailingAddress,Street].와 같이 Path 절에서 인덱서와 하위 속성을 혼합할 수 있습니다.

  • 인덱서 내부에서 여러 인덱서 매개 변수를 쉼표(,)로 구분할 수 있습니다. 각 매개 변수의 형식은 괄호를 사용하여 지정할 수 있습니다. 예를 들어 Path="[(sys:Int32)42,(sys:Int32)24]"를 사용할 수 있으며 여기서 sysSystem 네임스페이스에 매핑됩니다.

  • 소스가 컬렉션 뷰인 경우 슬래시(/)를 사용하여 현재 항목을 지정할 수 있습니다. 예를 들어 Path=/ 절은 뷰의 현재 항목에 대한 바인딩을 설정합니다. 소스가 컬렉션인 경우 이 구문은 기본 컬렉션 뷰의 현재 항목을 지정합니다.

  • 속성 이름과 슬래시를 결합하여 컬렉션인 속성을 트래버스할 수 있습니다. 예를 들어 Path=/Offices/ManagerName은 소스 컬렉션의 현재 항목을 지정하며 여기에는 컬렉션인 Offices 속성이 포함됩니다. 현재 항목은 ManagerName 속성을 포함하는 개체입니다.

  • 필요에 따라 마침표(.) 경로를 사용하여 현재 소스에 바인딩할 수 있습니다. 예를 들어 Text="{Binding}"Text="{Binding Path=.}"와 같습니다.

이스케이프 메커니즘

  • 인덱서([ ]) 안의 캐럿 문자(^)는 다음 문자를 이스케이프합니다.

  • XAML에서 Path를 설정한 경우 XML 언어 정의와 관련된 특정 문자도 이스케이프(XML 엔터티 사용)해야 합니다.

    • "&" 문자를 이스케이프하려면 &amp;를 사용합니다.

    • ">" 끝 태그를 이스케이프하려면 &gt;를 사용합니다.

  • 또한 태그 확장 구문을 사용하여 특성의 전체 바인딩을 설명하는 경우 WPF 태그 확장 파서와 관련된 문자를 이스케이프(백슬래시 \ 사용)해야 합니다.

    • 백슬래시(\)는 그 자체로 이스케이프 문자입니다.

    • 등호(=)는 속성 값에서 속성 이름을 구분합니다.

    • 쉼표(,)는 속성을 구분합니다.

    • 오른쪽 중괄호(})는 태그 확장의 끝입니다.

바인딩 방향

Binding.Mode 속성을 사용하여 바인딩 방향을 지정합니다. 다음 모드는 바인딩 업데이트에 사용할 수 있는 옵션입니다.

바인딩 모드 설명
BindingMode.TwoWay 대상 속성 또는 원본 속성이 변경될 때마다 대상 속성 또는 속성을 업데이트합니다.
BindingMode.OneWay 원본 속성이 변경된 경우에만 대상 속성을 업데이트합니다.
BindingMode.OneTime 애플리케이션이 시작되거나 DataContext가 변경된 경우에만 대상 속성을 업데이트합니다.
BindingMode.OneWayToSource 대상 속성이 변경될 때 원본 속성을 업데이트합니다.
BindingMode.Default 대상 속성의 기본 Mode 값이 사용되도록 합니다.

자세한 내용은 BindingMode 열거형을 참조하세요.

다음 예제는 Mode 속성을 설정하는 방법을 보여 줍니다.

<TextBlock Name="IncomeText" Text="{Binding Path=TotalIncome, Mode=OneTime}" />

소스 변경 내용을 검색하려면(OneWayTwoWay 바인딩에 적용 가능) 소스에서 INotifyPropertyChanged와 같은 적절한 속성 변경 알림 메커니즘을 구현해야 합니다. 자세한 내용은 변경 알림 제공을 참조하세요.

TwoWay또는 OneWayToSource 바인딩의 경우 UpdateSourceTrigger 속성을 설정하여 원본 업데이트의 타이밍을 제어할 수 있습니다. 자세한 내용은 UpdateSourceTrigger를 참조하세요.

기본 동작

선언에서 지정되지 않은 경우 기본 동작은 다음과 같습니다.

  • 바인딩 소스 값과 바인딩 대상 값 간에 형식을 변환하는 기본 변환기가 만들어집니다. 변환을 만들 수 없는 경우 기본 변환기는 null을 반환합니다.

  • ConverterCulture를 설정하지 않으면 바인딩 엔진은 바인딩 대상 개체의 Language 속성을 사용합니다. XAML에서 이 값을 명시적으로 설정하지 않은 경우 기본적으로 en-US로 설정되거나 페이지 루트 요소(또는 임의의 요소)에서 값이 상속됩니다.

  • 바인딩에 이미 데이터 컨텍스트가 있고(예: 부모 요소에서 데이터 컨텍스트가 상속된 경우) 컨텍스트에서 반환 중인 항목 또는 컬렉션이 경로 수정 없이도 바인딩에 적합한 경우 바인딩 선언에 절을 사용하지 않아도 됩니다({Binding}). 이러한 방법으로 데이터 스타일링에 바인딩이 지정되는 경우가 종종 있으며 이 경우 바인딩이 컬렉션에 대해 작동됩니다. 자세한 내용은 바인딩 원본으로 전체 개체 사용을 참조하세요.

  • 바인딩되는 종속성 속성에 따라 단방향과 양방향의 기본 Mode가 달라집니다. 바인딩이 원하는 대로 동작하도록 항상 바인딩 모드를 명시적으로 선언할 수 있습니다. 일반적으로 TextBox.TextRangeBase.Value처럼 사용자가 편집 가능한 컨트롤 속성의 기본값은 양방향 바인딩으로 설정되지만 대부분의 다른 속성 기본값은 단방향 바인딩으로 설정됩니다.

  • 바인딩된 종속성 속성에 따라서도 PropertyChangedLostFocus의 기본 UpdateSourceTrigger 값이 다릅니다. 대부분의 종속성 속성에 대한 기본값이 PropertyChanged인 반면 TextBox.Text 속성의 기본값은 LostFocus입니다.

참고 항목