c#/WPF

[WPF] Binding 속성들

루다대디 2024. 7. 26. 09:15

Binding에서 제공해주는 여러 속성들을 정리해보려고한다

 

WPF에서 Binding속성은 XAML에서 UI 요소를 데이터 소스의 속성과 연결하는 데 사용된다.

Binding은 여러 속성을 제공하여 다양한 방법으로 데이터를 연결 할 수 있게 도와준다.

어떤 속성들이 있고, 해당 속성이 어떤 역할을 하는지 알아보자

  

목차

Path
Source
ElementName
RelativeSource
Mode
UpdateSourceTrigger
Converter
ConverterParameter
StringFormat
FallbackValue
TargetNullValue

 

 


Path

바인딩할 데이터 소스의 속성 경로를 지정

<!--WPF는 내부적으로 이를 Path 속성에 대한 값으로 해석-->
<TextBlock Text="{Binding Title}" />

<!--Binding 객체의 Path 속성을 명시적으로 지정-->
<TextBlock Text="{Binding Path=Title}" />

Source

바인딩할 데이터 소스를 지정

 

1
공통으로 관리하는 테마Color, 폰트 등을 활용할 수 있다.

<!-- App.xaml 리소스에 추가-->
<SolidColorBrush x:Key="TitleColor" Color="Blue"/>
<TextBlock Text="{Binding Title}" Foreground="{Binding Source={StaticResource TitleColor}}"/>



2
Person 객체의 Name 속성과 바인딩
이렇게 써본적은 없지만 가능은하다

public class Person
{
    public string Name { get; set; }
}
<Window.Resources>
	<local:Person x:Key="person" Name="Seung Soo Lee" />
</Window.Resources>
    
<TextBlock Text="{Binding Source={StaticResource person}, Path=Name}"/>

ElementName

바인딩할 데이터 소스로 사용할 다른 요소의 이름을 지정

TextBox의 Text 속성을 TextBlock의 Text 속성에 바인딩
TextBox에 텍스트를 입력하면 TextBlock이 해당 텍스트를 실시간으로 표시하는 예제

    <Grid>
        <StackPanel>
            <TextBox x:Name="InputTextBox" Width="200" Margin="10" />
            <TextBlock Text="{Binding ElementName=InputTextBox, Path=Text}" FontSize="16" Margin="10" />
        </StackPanel>
    </Grid>

RelativeSource

바인딩할 데이터 소스로 사용할 상대 경로를 지정

Button 상위 요소중에서 Window 타입의 요소를 찾아
Window타입 요소의 Title을 바인딩하는 예제

<Window x:Class="WpfApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="RelativeSource 예제" Height="200" Width="300">
    <Grid>
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
            <Button Content="{Binding RelativeSource={RelativeSource AncestorType=Window}, Path=Title}" Width="200" Height="50" />
        </StackPanel>
    </Grid>
</Window>

Mode

바인딩 모드를 지정
(OneWay, TwoWay, OneWayToSource, OneTime)

 

OneWay
소스의 값이 변경되면 대상에 반영되지만, 대상의 값이 변경되어도 소스에는 반영되지 않는다

TwoWay
모드는 소스와 대상 모두의 값이 변경되면 서로에게 반영된다

OneWayToSource
대상의 값이 변경되면 소스에 반영되지만, 소스의 값이 변경되어도 대상에는 반영되지 않는다

OneTime
바인딩이 처음 설정될 때 한 번만 값을 가져오고 이후에는 업데이트되지 않는다


Default
default값은 속성마다 다르다
TextBox의 경우 default는 TwoWay이고, TexBlock의 경우에는 OneWay이다

<TextBlock Text="{Binding Name, Mode=OneWay}"/>
<TextBlock Text="{Binding Name, Mode=TwoWay}"/>
<TextBlock Text="{Binding Name, Mode=OneWayToSource}"/>
<TextBlock Text="{Binding Name, Mode=OneTime}"/>
<TextBlock Text="{Binding Name, Mode=Default}"/>

Mode

데이터소스가 업데이트되는 시점을 지정
주요 값으로는
PropertyChanged, LostFocus, Explicit등 이 있다

PropertyChanged
바인딩된 속성이 변경될 때마다 데이터 소스를 업데이트한다
아래 예제에서는 TextBox에 문자열을 입력하면 TextBlock에 바로 나타난다

<TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"/>
<TextBlock Text="{Binding Name}" />



LostFocus
바인딩된 요소가 포커스를 잃을 때 데이터 소스를 업데이트한다
아래 예제에서는 TextBox에 문자열을 입력한 후
TextBox가 포커스를 잃는 순간에 TextBlock에 나타난다

<TextBox Text="{Binding Name, UpdateSourceTrigger=LostFocus}"/>
<TextBlock Text="{Binding Name}"/>



Explicit
바인딩된 요소에서 명시적으로 소스 업데이트를 트리거할 때 데이터 소스를 업데이트한다
UpdateSource() 메서드를 호출해야한다.

<TextBox x:Name="InputTextBox" Text="{Binding Name, UpdateSourceTrigger=Explicit}"/>
<TextBlock Text="{Binding Name}"/>
<Button Click="Button_Click"/>
private void Button_Click(object sender, RoutedEventArgs e)
{
    var binding = InputTextBox.GetBindingExpression(System.Windows.Controls.TextBox.TextProperty);
    binding.UpdateSource();
}

 


Converter

바인딩 데이터를 변환하는 데 사용할 변환기를 지정

Converter를 사용하면 바인딩된 데이터의 형식을 변환할 수 있다
아래 예제에서는 TextBox에 값을 입력하면
대문자로 Convert되어 TextBlock에 보여진다

1
IValueConverter 인터페이스를 상속받는 Class가 필요함

public class UpperCaseConverter : IValueConverter
{
    // Convert 메서드는 소스 값을 대상 값으로 변환한다
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 값이 문자열인지 확인한다
        if (value is string stringValue)
        {
            // 문자열을 대문자로 변환하여 반환한다
            return stringValue.ToUpper();
        }
        // 값이 문자열이 아니면 그대로 반환한다
        return value;
    }

    // ConvertBack 메서드는 대상 값을 소스 값으로 변환한다
    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // 값이 문자열인지 확인한다
        if (value is string stringValue)
        {
            // 문자열을 소문자로 변환하여 반환한다
            return stringValue.ToLower();
        }
        // 값이 문자열이 아니면 그대로 반환한다
        return value;
    }
}



2
Converter를 리소스로 정의하고 Key값을 이용해 바인딩에 사용

<Window.Resources>
    <local:UpperCaseConverter x:Key="upperCaseConverter" />
</Window.Resources>
<Grid>
    <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center">
        <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}" />
        <TextBlock Text="{Binding Name, Converter={StaticResource upperCaseConverter}}" />
    </StackPanel>
</Grid>

ConverterParameter

변환기에 전달할 매개변수를 지정

ConverterParameter를 사용하여
위에서작성한 Convert에 추가로 매개변수를 전달해 줄 수 있다

1
IValueConverter 인터페이스를 상속받는 Class가 필요함

public class CaseConverter: IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is string stringValue)
        {
            // 파라미터 값이 문자열인지 확인한다
            if (parameter is string param)
            {
                // 파라미터 값에따라 처리한다
                if(param == "upper")
                {
                    return stringValue.ToUpper();
                }
                else if(param == "lower")
                {
                    return stringValue.ToLower();
                }
            }
        }
        return value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        // Convert와 동일하게작성
    }
}

 


2
Converter를 리소스로 정의하고 Key값을 이용해 바인딩에 사용
ConverterParameter로 매개변수 전달

<Window.Resources>
    <local:CaseConverter x:Key="caseConverter" />
</Window.Resources>
<Grid>
    <StackPanel HorizontalAlignment="Center"
                VerticalAlignment="Center">
        <TextBox Text="{Binding Name, UpdateSourceTrigger=PropertyChanged}"
                 />
        <!-- 대문자로 변환 -->
        <TextBlock Text="{Binding Name, Converter={StaticResource caseConverter}, ConverterParameter=upper}"/>
        <!-- 소문자로 변환 -->
        <TextBlock Text="{Binding Name, Converter={StaticResource caseConverter}, ConverterParameter=lower}" />
    </StackPanel>
</Grid>

StringFormat

바인딩 데이터를 문자열로 포맷하는 방법을 지정

DateTime을 문자열로 포맷하는 예제

<!-- DateTime형식 ex> 1992-01-22 -->
<TextBlock Text="{Binding TestDate, StringFormat='{}{0:yyyy-MM-dd}'}" />

<!-- DateTime형식 ex> January 22, 1992 -->
<TextBlock Text="{Binding TestDate, StringFormat='{}{0:MMMM dd, yyyy}'}" />

<!-- 소수점 아래 두 자리까지 표시, 마지막 반올림 ex> 값이 1.159이면 1.16으로 표기-->
<TextBlock Text="{Binding Amount, StringFormat='{}{0:F2}'}" />

<!-- 천 단위 구분 기호 사용 ex> 12,000 -->
<TextBlock Text="{Binding Amount, StringFormat='{}{0:N0}'}" />

<!-- 백분율 ex> 1 : 100% , 0.25 : 25% 소수점은 P1, P2-->
<TextBlock Text="{Binding Amount, StringFormat='{}{0:P0}'}" />

FallbackValue

바인딩할 수 없을때 사용할 값을 지정

FallbackValue는 바인딩이 실패 했을때 사용할 값을 지정하는 속성이다
아래 예제에서
Name이라는 변수가 없다고 가정하면 TextBlock에는 기본값인 "이승수"가 노출된

<TextBlock Text="{Binding Name, FallbackValue='이승수'}"/>

TargetNullValue

소스 값이 null일 때 사용할 값을 지정

TargetNullValue는 바인딩된 값이 null일 때 표시할 값을 지정하는 속성이다
아래 예제에서는
Button을 클릭했을때 Name을 null로 지정해주었다
그러면 Button을 클릭했을때 TextBlock에는 기본값인 "이승수"가 노출된다

<TextBlock Text="{Binding Name, TargetNullValue='이승수'}"/>
<Button Command="{Binding TestCommand}"/>