.NET MAUI - Binding 경로 (Path)

2022. 7. 27. 00:00MAUI

반응형

Path 는 참조되는 Binding Class 의 그 자체 속성, 서브 속성 또는 Collection 의 멤버를 지정할 수 있다.

예를 들어 보겠다. 

<TimePicker x:Name="timePicker">

위 TimePicker 의 Time 속성은 TimeSpan 형식이며 TotalSeconds 속성이 있다.

해당 속성을 참조하는 데이터 바인딩을 Path 를 이용하여 만들어 보자

{Binding Source={x:Reference timePicker},
         Path=Time.TotalSeconds}

그럼 다음 예제를 확인해 보자

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:globe="clr-namespace:System.Globalization;assembly=System.Runtime"
             x:Class="MauiApp1.Xaml.BindingPath.MainPage"
             Title="MainPage"
             x:Name="page">
    <ContentPage.Resources>
        <Style TargetType="Label">
            <Setter Property="FontSize" Value="18" />
            <Setter Property="HorizontalTextAlignment" Value="Center" />
            <Setter Property="VerticalOptions" Value="Center" />
        </Style>
    </ContentPage.Resources>

    <StackLayout Margin="10, 0">
        <TimePicker x:Name="timePicker" />
        <Label Text="{Binding Source={x:Reference timePicker},
                              Path=Time.TotalSeconds,
                              StringFormat='{0} total seconds'}" />
        <Label Text="{Binding Source={x:Reference page},
                              Path=Content.Children.Count,
                              StringFormat='There are {0} children in this StackLayout'}" />
        <Label Text="{Binding Source={x:Static globe:CultureInfo.CurrentCulture},
                              Path=DateTimeFormat.DayNames[3],
                              StringFormat='The middle day of the week is {0}'}" />
        <Label>
            <Label.Text>
                <Binding Path="DateTimeFormat.DayNames[3]"
                         StringFormat="The middle day of the week in France is {0}">
                    <Binding.Source>
                        <globe:CultureInfo>
                            <x:Arguments>
                                <x:String>fr-FR</x:String>
                            </x:Arguments>
                        </globe:CultureInfo>
                    </Binding.Source>
                </Binding>
            </Label.Text>
        </Label>
        <Label Text="{Binding Source={x:Reference page},
                              Path=Content.Children[1].Text.Length,
                              StringFormat='The second Label has {0} characters'}" />
    </StackLayout>
</ContentPage>

두 번째 레이블에서 바인딩 소스는 Page 자체 이다.

Content 속성은 IList<View> 형식의 Children 속성이 있는 StackLayout 형식이며,

여기에는 자식 수를 나타내는 Count 속성이 있다.

 

위의 예에서 세 번째 Label의 바인딩은 System.Globalization 네임스페이스의 CultureInfo 클래스를 참조한다.

<Label Text="{Binding Source={x:Static globe:CultureInfo.CurrentCulture},
                      Path=DateTimeFormat.DayNames[3],
                      StringFormat='The middle day of the week is {0}'}" />

소스는 CultureInfo 유형의 개체인 정적 CultureInfo.CurrentCulture 속성으로 설정된다.

클래스는 DayNames 컬렉션을 포함하는 DateTimeFormatInfo 유형의 DateTimeFormat이라는 속성을 정의한다.

인덱스는 네 번째 항목을 선택한다.네 번째 레이블은 유사하지만 프랑스와 관련된 문화에 대해 수행한다.

바인딩의 Source 속성은 생성자를 사용하여 CultureInfo 개체로 설정된다.

<Label>
    <Label.Text>
        <Binding Path="DateTimeFormat.DayNames[3]"
                 StringFormat="The middle day of the week in France is {0}">
            <Binding.Source>
                <globe:CultureInfo>
                    <x:Arguments>
                        <x:String>fr-FR</x:String>
                    </x:Arguments>
                </globe:CultureInfo>
            </Binding.Source>
        </Binding>
    </Label.Text>
</Label>

 

마지막 Label은 StackLayout의 자식 중 하나를 참조한다는 점을 제외하고 두 번째와 유사하다.

<Label Text="{Binding Source={x:Reference page},
                      Path=Content.Children[1].Text.Length,
                      StringFormat='The first Label has {0} characters'}" />

그 자식은 Length 속성이 있는 String 유형의 Text 속성이 있는 Label이다. 첫 번째 레이블은 TimePicker에 설정된 TimeSpan을 보고하므로 해당 텍스트가 변경되면 최종 레이블도 변경된다.

 

복잡한 경로 디버그

복잡한 경로 정의는 구성하기 어려울 수 있다. 다음 하위 속성을 올바르게 추가하려면 각 하위 속성의 유형이나 컬렉션의 항목 유형을 알아야 하지만 유형 자체는 경로에 나타나지 않다. 한 가지 기술은 경로를 점진적으로 구축하고 중간 결과를 확인하는 것이다. 마지막 예에서는 경로 정의 없이 시작할 수 있다.

<Label Text="{Binding Source={x:Reference page},
                      StringFormat='{0}'}" />

바인딩 소스 또는 DataBindingDemos.PathVariationsPage의 유형을 표시한다.

PathVariationsPage는 ContentPage에서 파생되므로 Content 속성이 있다.

 

<Label Text="{Binding Source={x:Reference page},
                      Path=Content,
                      StringFormat='{0}'}" />

Content 속성의 유형은 이제 Microsoft.Maui.Controls.StackLayout으로 표시된다. Path에 Children 속성을 추가하고 형식도 Microsoft.Maui.Controls.StackLayout이다. 여기에 인덱스를 추가하면 유형은 Microsoft.Maui.Controls.Label이다.

 

.NET MAUI는 바인딩 경로를 처리할 때 INotifyPropertyChanged 인터페이스를 구현하는 경로의 모든 개체에 PropertyChanged 처리기를 설치한다. 예를 들어, Text 속성이 변경되기 때문에 최종 바인딩은 첫 번째 Label의 변경에 반응한다. 바인딩 경로의 속성이 INotifyPropertyChanged를 구현하지 않으면 해당 속성에 대한 모든 변경 사항이 무시된다. 일부 변경 사항은 바인딩 경로를 완전히 무효화할 수 있으므로 속성 및 하위 속성 문자열이 무효화되지 않는 경우에만 이 기술을 사용해야 한다.

 

BindableObject 를 상속한 모든 View (Control) 은 INotifyPropertyChanged 를 구현 하였다.

 

관련영상

https://youtu.be/ebUw4FbsUuk

 

 

반응형

'MAUI' 카테고리의 다른 글

.NET MAUI - Binding Relative bindings  (0) 2022.07.29
.NET MAUI - Binding Value Converters  (0) 2022.07.28
.NET MAUI - Binding 모드  (0) 2022.07.26
.NET MAUI - Binding 기본  (0) 2022.07.25
.NET MAUI - XAML stack navigation  (0) 2022.07.22