WPF RelativeSources 2022에 대한 간단한 가이드 | 아이포 테크노랩

WPF RelativeSource는 해당 관계를 사용하여 요소의 데이터를 다른 소스 요소와 바인딩하는 데 도움이 되는 마크업 확장입니다. 주어진 요소에 상대적으로 떨어지는 소스 위치에 대해 설명합니다.

다른 객체의 속성이나 상대 부모에 대한 모든 객체의 Bindings 속성과 함께 사용할 수 있습니다. 대상 요소 유형의 위치를 ​​기준으로 위치를 지정하여 소스의 바인딩 속성을 가져오거나 설정합니다. 기본값은 NULL입니다.

{ 및 }(중괄호)는 XAML에서 모든 태그 확장 코드를 작성하는 데 사용됩니다. 태그 확장 특성에 대한 구문입니다. 그리고 이를 통해서만 XAML 프로세서는 마크업 확장이 특정 속성을 처리해야 한다고 진단한다.

상대 소스 모드



셀프 모드



이 모드는 개체가 자신의 속성을 자신의 다른 속성이나 부모에 바인딩할 때 사용됩니다. 즉, 소스 요소가 대상 속성과 유사할 때 이 모드를 사용할 수 있습니다.


<window height="300" mc:ignorable="d" title="Self Property" width="300" windowstartuplocation="CenterScreen" x:class="RelativeSrc.SelfProp" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:RelativeSrc" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <border borderbrush="Black" borderthickness="5" cornerradius="5">
        <grid background="DimGray">
            <textblock fontsize="30" foreground="Black" horizontalalignment="Center" margin="0 
 20" text="Self Property">
            <ellipse height="100" stroke="Cornsilk" strokethickness="4" width="{Binding 
      RelativeSource={RelativeSource Self}, Path=Parent.ActualHeight}">
                <ellipse.fill>
                    <lineargradientbrush endpoint="1,1" startpoint="0,0">
                        <gradientstop color="Cornsilk" offset="0">
                        <gradientstop color="Sienna" offset="0.5">
                        <gradientstop color="Goldenrod" offset="0.7">
                        <gradientstop color="PaleGoldenrod" offset="1">
                    </gradientstop></gradientstop></gradientstop></gradientstop></lineargradientbrush>
                </ellipse.fill>
            </ellipse>
        </textblock></grid>
    </border>
</window>  





이 속성은 내부에 부모 속성이 정의되어 있으므로 지정된 요소의 속성을 모든 요소의 직접 부모 중 하나에 연결하는 데 사용됩니다. 여기서 창 높이는 Ellipse 너비의 부모입니다.

조상 찾기 모드



이 모드는 셀프 모드와 유사합니다. 유일한 차이점은 여기에서 실제 속성이 정의된 요소의 조상 또는 부모를 선택할 수 있다는 것입니다. 값을 제공하는 두 가지 속성, 즉 조상 유형과 조상 순위가 있습니다.


<window height="250" mc:ignorable="d" title="FindAncestor Property" width="400" windowstartuplocation="CenterScreen" x:class="RelativeSrc.AncestorProp" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:RelativeSrc" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <canvas name="Parent_0">
        <border borderbrush="Aquamarine" borderthickness="15" height="{Binding RelativeSource={RelativeSource Self}, Path=Parent.ActualHeight}" name="Parent_1" width="{Binding RelativeSource={RelativeSource Self}, 
Path=Parent.ActualWidth}">
            <canvas name="Parent_2">
                <border borderbrush="MediumVioletRed" borderthickness="10" height="{Binding RelativeSource={RelativeSource Self}, Path=Parent.ActualHeight}" name="Parent_3" width="{Binding RelativeSource={RelativeSource Self}, 
      Path=Parent.ActualWidth}">
                    <canvas name="Parent_4">



       <border borderbrush="Pink" borderthickness="10" height="{Binding RelativeSource={RelativeSource Self}, 
                 Path=Parent.ActualHeight}" name="Parent_5" width="{Binding RelativeSource={RelativeSource Self}, 
              Path=Parent.ActualWidth}">
                            <canvas name="Parent_6">
                                <textblock background="LightSkyBlue" fontsize="17" margin="4 5" padding="15 10" text="Displaying the Name of the Ancestor">
                                <textblock fontsize="22" margin="110 70" text="{Binding 
                      RelativeSource={RelativeSource FindAncestor,
                                   AncestorType={x:Type Canvas}, AncestorLevel=3},Path=Name}" width="90">
                            </textblock></textblock></canvas>
                        </border>
                    </canvas>
                </border>
            </canvas>
        </border>
    </canvas>
</window>





자세히 알아보기: Wpf 및 Uwp용 Visual Studio 2019의 Xaml 개발자 도구의 새로운 기능은 무엇입니까?



TemplatedParent 모드



컨트롤 템플릿 속성을 컨트롤 템플릿이 적용되는 다른 컨트롤과 연결합니다. 이때 어떤 컨트롤의 ControlTemplate에 속성을 적용해야 할 때 이 방법을 사용할 수 있습니다.


<window height="200" mc:ignorable="d" title="TemplatedParentProp" width="400" windowstartuplocation="CenterScreen" x:class="RelativeSrc.TemplatedParentProp" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:RelativeSrc" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <stackpanel background="Lavender"><button background="Transparent" content="This is Button of Parent Control" height="20" margin="20" name="btn" width="200">
            <button.template>
                <controltemplate targettype="Button">
                    </controltemplate></button.template></button><button background="{Binding RelativeSource={RelativeSource TemplatedParent} , 
          Path=Background}" click="btn_Click" content="{TemplateBinding Content}"></button>
        <textblock background="LightGray" margin="100 50" padding="10" text="{Binding 
ElementName=btn,Path=Content}">
    </textblock></stackpanel>
</window>





컴파일 시 평가되는 TemplateBinding이라는 유사한 속성을 사용할 수 있습니다. 실행 시 먼저 실행되는 TemplatedParent의 줄임말입니다.

이전데이터 모드



이 모드는 RelativeSource 모드의 모든 모드 중에서 매우 혼란스럽고 덜 사용되는 모드입니다. 개별적인 경우에 사용됩니다. 이 방법의 의제는 모든 컨트롤의 값을 새 값에 연결하는 것입니다. 예를 들어 다른 텍스트 상자나 텍스트 블록에서 텍스트 상자의 값을 사용해야 하는 경우 PreviousData 모드를 사용할 수 있습니다. 그리고 이것으로부터 우리는 항목 컨트롤과 함께 이 모드를 사용해야 한다는 것을 알게 됩니다.

예시:

먼저 사용자 지정 컬렉션을 사용하여 ItemsControl을 만듭니다.


class Items : ObservableCollection<item>
{
        public Items()
        {
            Add(new Item { Value = 110.30 });
            Add(new Item { Value = 200 });
            Add(new Item { Value = 70.89 });
            Add(new Item { Value = 123.45 });
            Add(new Item { Value = 222.00 });
            Add(new Item { Value = 50.50 });
        }
}
</item>



WPF 앱 개발 회사를 고용할 계획입니까? 귀하의 검색은 여기서 끝납니다.



여기서는 Item 타입의 ObservableCollection을 사용합니다. double 유형의 값은 하나만 있습니다.

이제 항목에 대한 클래스를 만듭니다.

namespace RelativeSrc
{
    class Item : INotifyPropertyChanged
    {
        private double _value;

        public double Value
        {
            get { return _value; }
            set { _value = value; OnPropertyChanged("Value"); }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string PropertyName)
        {
            if (null != PropertyChanged)
            {
                PropertyChanged(this,
                     new PropertyChangedEventArgs(PropertyName));
            }
        }
    }
}



이제 ItemsControl을 데이터 컬렉션에 바인딩하기 위해 DataContext 속성의 생성자 수준 컬렉션을 전체 문서로 설정합니다.


public partial class PreviousDataProp: Window
{
   public PreviousDataProp()
   {
      InitializeComponent();
      this.DataContext = new Items();
    }
}        



이제 Binding 속성이 있는 ItemsControl을 추가하여 ItemsControl의 실제 보기에서 약간의 개선을 관찰할 수 있습니다.


<window height="400" mc:ignorable="d" title="PreviousDataProp" width="700" x:class="RelativeSrc.PreviousDataProp" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:RelativeSrc" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <grid>
        <itemscontrol itemssource="{Binding}" margin="10 30">
            <itemscontrol.rendertransform>
                <transformgroup>
                    <scaletransform scaley="-1">
                    <translatetransform y="300">
                </translatetransform></scaletransform></transformgroup>
            </itemscontrol.rendertransform>
            <itemscontrol.itemspanel>
                <itemspaneltemplate>
                    <stackpanel orientation="Horizontal">
                </stackpanel></itemspaneltemplate>
            </itemscontrol.itemspanel>
            <itemscontrol.itemtemplate>
                <datatemplate>
                    <stackpanel>
                        <border background="LightSeaGreen" borderbrush="CornflowerBlue" borderthickness="3" cornerradius="3" height="{Binding 
                            Value}" margin="0,0,35,0" width="80">
                            <textblock fontweight="bold" foreground="Yellow" horizontalalignment="Center" text="{Binding Value}" verticalalignment="Center">
                                <textblock.rendertransform>
                                    <transformgroup>
                                        <scaletransform scaley="-1">
                                    </scaletransform></transformgroup>
                                </textblock.rendertransform>
                            </textblock>
                        </border>
                    </stackpanel>
                </datatemplate>
            </itemscontrol.itemtemplate>
        </itemscontrol>
    </grid>
</window>



이 코드는 Items 컬렉션에 지정된 실제 현재 데이터만 표시합니다. 컬렉션의 이전 데이터를 가져오려면 PreviousData 속성이 있는 하나의 텍스트 블록을 추가해야 합니다. 그리고 이 텍스트 블록에서 이전 테두리 값의 값을 항목 목록 컨트롤에 추가하고 이를 통해 시각화된 실제 출력을 얻습니다.


<textblock fontsize="14" fontweight="bold" margin="20" text="{Binding 
  RelativeSource={RelativeSource PreviousData}, Path=Value}">
             <textblock.rendertransform>
                      <scaletransform scaley="-1">
</scaletransform></textblock.rendertransform>
</textblock>





여기에서 최근에 추가한 새 텍스트 블록에 이전 항목의 값이 표시되는 것을 볼 수 있습니다.

결론



아시다시피 RelativeSource는 마크업 확장입니다. 따라서 마크업 확장은 일반적으로 속성 값을 다른 리터럴이나 이름 지정된 핸들러의 값으로 이스케이프해야 할 때 구현됩니다. 그러나 요구 사항은 형식 변환기가 속성이나 형식을 결정하는 것뿐만 아니라 전역적이어야 합니다.

좋은 웹페이지 즐겨찾기