수색…
통사론
- {Binding PropertyName} 은 {Binding Path = PropertyName} 과 동일합니다.
- {바인딩 경로 = SomeProperty.SomeOtherProperty.YetAnotherProperty}
- {바인딩 경로 = SomeListProperty [1]}
매개 변수
매개 변수 | 세부 |
---|---|
통로 | 바인딩 할 경로를 지정합니다. 지정하지 않으면 DataContext 자체에 바인딩됩니다. |
UpdateSourceTrigger | 바인딩 소스의 값이 업데이트되는시기를 지정합니다. 기본값은 LostFocus 입니다. 가장 많이 사용되는 값은 PropertyChanged 입니다. |
방법 | 일반적으로 OneWay 또는 TwoWay . 바인딩에 의해 지정되지 않은 경우, 바인딩 대상이 TwoWay 가되도록 요청하지 않는 한 기본값은 OneWay 입니다. TwoWay 를 사용하여 읽기 전용 속성에 바인딩 할 때 오류가 발생합니다. 예를 들어 읽기 전용 문자열 속성을 TextBox.Text 바인딩 할 때 OneWay 를 명시 적으로 설정해야합니다. |
출처 | StaticResource 를 현재 DataContext 대신 바인딩 소스로 사용할 수 있습니다. |
관련 소스 | 다른 XAML 요소를 현재 DataContext 대신 바인딩 원본으로 사용할 수 있습니다. |
요소 이름 | 명명 된 XAML 요소를 현재 DataContext 대신 바인딩 원본으로 사용할 수 있습니다. |
FallbackValue | 바인딩에 실패하면이 값이 바인딩 대상에 제공됩니다. |
TargetNullValue | Y 인딩 소스 값이 null ,이 값은 Y 인딩 대상에 제공됩니다. |
변환기 | 바인딩 값을 변환하는 데 사용되는 변환기 StaticResource 를 지정합니다. 예 : 부울을 Visibility 열거 항목으로 변환합니다. |
ConverterParameter | 변환기에 제공 할 선택적 매개 변수를 지정합니다. 이 값은 정적이어야하며 바인딩 할 수 없습니다. |
StringFormat | 바운드 값을 표시 할 때 사용할 형식 문자열을 지정합니다. |
지연 | (WPF 4.5 이상) 바인딩에서 ViewModel 의 BindingSource 를 업데이트하는 데 지연 milliseconds )을 지정 ViewModel . 적용하려면 Mode=TwoWay 및 UpdateSourceTrigger=PropertyChanged 와 함께 사용해야합니다. |
비고
UpdateSourceTrigger
기본적으로 WPF는 컨트롤이 포커스를 잃을 때 바인딩 원본을 업데이트합니다. 그러나 포커스를 얻을 수있는 컨트롤이 단 하나 (예제에서 일반적인 것) 인 경우 업데이트가 작동하려면 UpdateSourceTrigger=PropertyChanged
를 지정해야합니다.
모든 키 스트로크에서 바인딩 소스를 업데이트하는 것이 값 비싸지 않거나 실제 데이터 유효성 검사가 바람직하지 않은 경우가 아니면 많은 양방향 바인딩에서 PropertyChanged
를 트리거로 사용하려고합니다.
LostFocus
를 사용하면 불행한 부작용이 있습니다. Enter 키를 누르면 IsDefault
라고 표시된 버튼을 사용하여 양식을 제출해도 바인딩을지지하는 속성이 업데이트되지 않으므로 변경 사항을 효과적으로 취소 할 수 있습니다. 다행히 몇 가지 해결 방법이 있습니다 .
또한 UWP와는 달리 WPF (4.5 이상)에는 바인딩에 Delay
속성이 있습니다. 일부 TextBox
유효성 검사와 같이 로컬 전용 또는 간단한 마이너 인텔리전스 설정을 사용하는 바인딩의 경우에는 충분할 수 있습니다.
부울을 가시성 값으로 변환
이 예제에서는 IValueConverter
를 사용하여 확인란을 선택하지 않으면 빨간색 상자 (테두리)를 숨 깁니다.
참고 : 아래 예제에서 사용 된 BooleanToVisibilityConverter
는 System.Windows.Controls 네임 스페이스에있는 기본 제공 값 변환기입니다.
XAML :
<Window x:Class="StackOverflowDataBindingExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Window.Resources>
<BooleanToVisibilityConverter x:Key="VisibleIfTrueConverter" />
</Window.Resources>
<StackPanel>
<CheckBox x:Name="MyCheckBox"
IsChecked="True" />
<Border Background="Red" Width="20" Height="20"
Visibility="{Binding Path=IsChecked,ElementName=MyCheckBox, Converter={StaticResource VisibleIfTrueConverter}}" />
</StackPanel>
</Window>
DataContext 정의하기
WPF에서 바인딩을 사용하려면 DataContext 를 정의해야합니다. DataContext는 바인딩에서 기본적으로 데이터를 가져올 위치를 알려줍니다.
<Window x:Class="StackOverflowDataBindingExample.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:StackOverflowDataBindingExample"
xmlns:vm="clr-namespace:StackOverflowDataBindingExample.ViewModels"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Window.DataContext>
<vm:HelloWorldViewModel />
</Window.DataContext>
...
</Window>
코드 숨김을 통해 DataContext를 설정할 수도 있지만 XAML IntelliSense는 다소 까다 롭습니다. 강력한 형식의 DataContext는 XAML에서 IntelliSense가 바인딩에 사용할 수있는 속성을 제안하도록 설정해야합니다.
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new HelloWorldViewModel();
}
}
보다 유연한 방식으로 DataContext를 정의하는 데 도움이되는 프레임 워크가 있지만 (예 : MVVM Light 에는 제어 반전 을 사용하는 뷰 모델 로케이터가 있음)이 튜토리얼에서는 빠르고 간단하게 메서드를 사용합니다.
WPF에서 거의 모든 시각적 요소에 대해 DataContext를 정의 할 수 있습니다. DataContext는 일반적으로 명시 적으로 재정의되지 않은 경우 (예 : ContentPresenter 내부)에 시각 트리의 조상에서 상속됩니다.
INotifyPropertyChanged 구현하기
INotifyPropertyChanged
는 사용자 인터페이스 또는 다른 컴포넌트가 속성이 변경되었음을 알 수 있도록 소스 (즉, DataContext)를 바인딩하는 데 사용되는 인터페이스입니다. WPF는 PropertyChanged
이벤트가 발생할 때 UI를 자동으로 업데이트합니다. 모든 뷰 모델이 상속 할 수있는 기본 클래스에서이 인터페이스를 구현하는 것이 바람직합니다.
C # 6에서는 다음이 필요합니다.
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string name = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}
}
이렇게하면 두 가지 방법으로 NotifyPropertyChanged
를 호출 할 수 있습니다.
-
NotifyPropertyChanged()
. 속성 CallerMemberName 덕분에 호출하는 setter에 대한 이벤트를 발생 시킵니다 . -
NotifyPropertyChanged(nameof(SomeOtherProperty))
, 이는 SomeOtherProperty에 대한 이벤트를 발생시킵니다.
C # 5.0을 사용하는 .NET 4.5 이상에서는 대신 다음을 사용할 수 있습니다.
public abstract class ViewModelBase : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
protected void NotifyPropertyChanged([CallerMemberName] string name = null)
{
var handler = PropertyChanged;
if (handler != null)
{
handler(this, new PropertyChangedEventArgs(name));
}
}
}
4.5 이전의 .NET 버전에서는 속성 이름을 문자열 상수로 표현 하거나 표현식을 사용하여 해결해야합니다 .
참고 : INotifyPropertyChanged
구현하지 않는 "일반 오래된 C # 개체"(POCO)의 속성에 바인딩하고 바인딩이 예상보다 잘 작동하는지 관찰 할 수 있습니다. 이것은 .NET의 숨겨진 기능이므로 피해야합니다. 특히 바인딩 Mode
가 OneTime
이 아닌 경우 메모리 누수가 발생합니다 ( 여기 참조).
INotifyPropertyChanged를 구현하지 않고 바인딩을 업데이트하는 이유는 무엇입니까?
다른 명명 된 요소의 속성에 바인딩
명명 된 요소의 속성에 바인딩 할 수 있지만 명명 된 요소는 범위 내에 있어야합니다.
<StackPanel>
<CheckBox x:Name="MyCheckBox" IsChecked="True" />
<TextBlock Text="{Binding IsChecked, ElementName=MyCheckBox}" />
</StackPanel>
조상의 재산에 귀속
RelativeSource
바인딩을 사용하여 시각적 트리에서 조상의 속성에 바인딩 할 수 있습니다. 같은 유형을 가지고 있거나 지정한 유형에서 파생 된 시각적 트리에서 가장 가까운 가장 가까운 컨트롤이 바인딩의 소스로 사용됩니다.
<Grid Background="Blue">
<Grid Background="Gray" Margin="10">
<Border Background="Red" Margin="20">
<StackPanel Background="White" Margin="20">
<Button Margin="10" Content="Button1" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Grid}}}" />
<Button Margin="10" Content="Button2" Background="{Binding Background, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type FrameworkElement}}}" />
</StackPanel>
</Border>
</Grid>
</Grid>
이 예제에서 가장 가까운 Grid
조상은 회색 배경을 가지고 있기 때문에 Button1 은 회색 배경을 갖습니다. Button2 는 FrameworkElement
에서 파생 된 가장 가까운 StackPanel
이 흰색 StackPanel
이기 때문에 흰색 배경을 가지고 있습니다.
다중 바인딩을 사용하여 여러 값 바인딩
MultiBinding을 사용하면 여러 값을 동일한 속성에 바인딩 할 수 있습니다. 다음 예제에서는 여러 값이 텍스트 상자의 Text 속성에 바인딩되고 StringFormat 속성을 사용하여 서식이 지정됩니다.
<TextBlock>
<TextBlock.Text>
<MultiBinding StringFormat="{}{0} {1}">
<Binding Path="User.Forename"/>
<Binding Path="User.Surname"/>
</MultiBinding>
</TextBlock.Text>
</TextBlock>
StringFormat
외에도 IMultiValueConverter
사용하여 Bindings의 값을 MultiBinding의 대상에 대한 하나의 값으로 변환 할 수 있습니다.
그러나 MultiBinding은 중첩 될 수 없습니다.