.net - source - wpf textblock binding




RelativeSource와 WPF 바인딩을 어떻게 사용합니까? (10)

Bechir Bejaoui는 WPF에서 RelativeSources의 유스 케이스를 그의 기사에서 다음과 같이 노출합니다.

RelativeSource는 객체의 속성을 상대 부모 중 다른 객체에 바인딩하려고 할 때 특정 객체의 속성을 객체 자체의 다른 속성에 바인딩하려고 할 때 특정 바인딩 사례에 사용되는 태그 확장입니다. 사용자 지정 컨트롤 개발의 경우 XAML 조각에 종속성 속성 값을 바인딩 할 때 마지막으로 일련의 바인딩 된 데이터의 차등을 사용하는 경우에 사용됩니다. 모든 상황은 상대 소스 모드로 표현됩니다. 나는 그 모든 사건들을 하나씩 공개 할 것이다.

  1. 모드 셀프 :

이 경우를 상상해보십시오. 높이가 항상 너비와 같기를 바라는 직사각형, 사각형이라고 가정 해 봅시다. 요소 이름을 사용하여이 작업을 수행 할 수 있습니다.

<Rectangle Fill="Red" Name="rectangle" 
                Height="100" Stroke="Black" 
                Canvas.Top="100" Canvas.Left="100"
                Width="{Binding ElementName=rectangle,
                Path=Height}"/>

그러나 위의 경우에 우리는 바인딩 객체의 이름, 즉 사각형을 나타내야합니다. 우리는 RelativeSource를 사용하여 다르게 동일한 목적을 달성 할 수 있습니다.

<Rectangle Fill="Red" Height="100" 
               Stroke="Black" 
               Width="{Binding RelativeSource={RelativeSource Self},
               Path=Height}"/>

이 경우 우리는 바인딩 객체의 이름을 언급 할 의무가 없으며 높이가 변경 될 때마다 너비가 항상 높이와 같습니다.

너비의 높이를 높이의 절반으로 지정하려면 Binding 태그 확장에 변환기를 추가하면됩니다. 이제 다른 사례를 상상해 봅시다.

 <TextBlock Width="{Binding RelativeSource={RelativeSource Self},
               Path=Parent.ActualWidth}"/>

위의 경우는이 요소가 Parent라는 속성을 보유하고 있으므로 주어진 요소의 특정 속성을 직접 부모 요소 중 하나에 연결하는 데 사용됩니다. 이것에 의해, FindAncestor 인 상대 소스 모드가됩니다.

  1. 모드 FindAncestor

이 경우 특정 요소의 속성은 부모 중 하나 인 Of Corse와 연결됩니다. 위의 경우와의 주요 차이점은 속성을 연결하기 위해 계층 구조에서 조상 유형 및 조상 순위를 결정하는 것은 사용자에게 달려 있다는 사실입니다. 그런데이 XAML 조각을 가지고 놀아보십시오.

<Canvas Name="Parent0">
    <Border Name="Parent1"
             Width="{Binding RelativeSource={RelativeSource Self},
             Path=Parent.ActualWidth}"
             Height="{Binding RelativeSource={RelativeSource Self},
             Path=Parent.ActualHeight}">
        <Canvas Name="Parent2">
            <Border Name="Parent3"
            Width="{Binding RelativeSource={RelativeSource Self},
           Path=Parent.ActualWidth}"
           Height="{Binding RelativeSource={RelativeSource Self},
              Path=Parent.ActualHeight}">
               <Canvas Name="Parent4">
               <TextBlock FontSize="16" 
               Margin="5" Text="Display the name of the ancestor"/>
               <TextBlock FontSize="16" 
                 Margin="50" 
            Text="{Binding RelativeSource={RelativeSource  
                       FindAncestor,
                       AncestorType={x:Type Border}, 
                       AncestorLevel=2},Path=Name}" 
                       Width="200"/>
                </Canvas>
            </Border>
        </Canvas>
     </Border>
   </Canvas>

위의 상황은 계층 적 부모를 나타내는 일련의 테두리와 캔버스 요소 내에 포함 된 두 개의 TextBlock 요소입니다. 두 번째 TextBlock은 상대 소스 레벨에서 지정된 상위의 이름을 표시합니다.

따라서 AncestorLevel = 2를 AncestorLevel = 1로 변경하고 어떻게되는지보십시오. 그런 다음 AncestorType = Border에서 AncestorType = Canvas로 조상 유형을 변경하고 어떤 일이 발생하는지 확인하십시오.

표시되는 텍스트는 Ancestor 유형 및 레벨에 따라 변경됩니다. 그런 다음 선조 수준이 조상 유형에 적합하지 않으면 어떻게됩니까? 이것은 좋은 질문입니다, 당신이 그것에 대해 물어볼 것입니다. 응답은 예외가 발생하지 않으며 예외가 TextBlock 수준에서 표시됩니다.

  1. TemplatedParent

이 모드는 주어진 ControlTemplate 속성을 ControlTemplate이 적용된 컨트롤의 속성에 연결합니다. 이 문제를 잘 이해하려면 여기에 예제가 있습니다.

<Window.Resources>
<ControlTemplate x:Key="template">
        <Canvas>
            <Canvas.RenderTransform>
                <RotateTransform Angle="20"/>
                </Canvas.RenderTransform>
            <Ellipse Height="100" Width="150" 
                 Fill="{Binding 
            RelativeSource={RelativeSource TemplatedParent},
            Path=Background}">

              </Ellipse>
            <ContentPresenter Margin="35" 
                  Content="{Binding RelativeSource={RelativeSource  
                  TemplatedParent},Path=Content}"/>
        </Canvas>
    </ControlTemplate>
</Window.Resources>
    <Canvas Name="Parent0">
    <Button   Margin="50" 
              Template="{StaticResource template}" Height="0" 
              Canvas.Left="0" Canvas.Top="0" Width="0">
        <TextBlock FontSize="22">Click me</TextBlock>
    </Button>
 </Canvas>

주어진 컨트롤의 속성을 컨트롤 템플릿에 적용하려면 TemplatedParent 모드를 사용할 수 있습니다. 이 마크 업 확장에는 첫 번째 짧은 핸드의 일종 인 TemplateBinding도 있지만 첫 번째 런타임 바로 후에 평가되는 TemplatedParent의 대비에서 TemplateBinding은 컴파일 타임에 평가됩니다. 아래 그림에서 설명 할 수 있듯이 배경과 내용이 버튼 내에서 컨트롤 템플릿에 적용됩니다.

WPF 바인딩으로 RelativeSource 를 사용하고 다른 유스 케이스는 무엇입니까?


RelativeSource를 더 쉽게 사용할 수 있도록 WPF의 바인딩 구문을 단순화하는 라이브러리를 만들었습니다. 여기 예시들이 있습니다. 전에:

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}
{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}
{Binding Path=Text, ElementName=MyTextBox}

후:

{BindTo PathToProperty}
{BindTo Ancestor.typeOfAncestor.PathToProperty}
{BindTo Template.PathToProperty}
{BindTo #MyTextBox.Text}

다음은 메소드 바인딩이 단순화되는 방법의 예입니다. 전에:

// C# code
private ICommand _saveCommand;
public ICommand SaveCommand {
 get {
  if (_saveCommand == null) {
   _saveCommand = new RelayCommand(x => this.SaveObject());
  }
  return _saveCommand;
 }
}

private void SaveObject() {
 // do something
}

// XAML
{Binding Path=SaveCommand}

후:

// C# code
private void SaveObject() {
 // do something
}

// XAML
{BindTo SaveObject()}

여기에서 라이브러리를 찾을 수 있습니다. http://www.simplygoodcode.com/2012/08/simpler-wpf-binding.html

메서드 바인딩을 위해 사용하는 'BEFORE'예제에서 코드는 이미 마지막으로 확인한 RelayCommand 를 사용하여 최적화되었습니다. 참고로 WPF의 기본 부분이 아닙니다. 그것 없이는 'BEFORE'사례는 훨씬 더 길었을 것입니다.


TemplatedParent : 잊지 마세요.

<Binding RelativeSource="{RelativeSource TemplatedParent}"/>

또는

{Binding RelativeSource={RelativeSource TemplatedParent}}

객체의 다른 속성에 바인딩하려는 경우 :

{Binding Path=PathToProperty, RelativeSource={RelativeSource Self}}

조상에 대한 소유권을 얻으려면 다음을 수행하십시오.

{Binding Path=PathToProperty,
    RelativeSource={RelativeSource AncestorType={x:Type typeOfAncestor}}}

템플릿 기반 부모에 대한 속성을 가져 오려면 (ControlTemplate에서 2 방향 바인딩을 할 수 있도록)

{Binding Path=PathToProperty, RelativeSource={RelativeSource TemplatedParent}}

또는 더 짧습니다 (OneWay 바인딩에만 해당).

{TemplateBinding Path=PathToProperty}

모든 대답을 읽지는 않았지만 버튼의 상대 소스 명령 바인딩의 경우이 정보를 추가하려고합니다.

Mode=FindAncestor 인 상대 소스를 사용하는 경우 바인딩은 다음과 같아야합니다.

Command="{Binding Path=DataContext.CommandProperty, RelativeSource={...}}"

경로에 DataContext를 추가하지 않으면 실행시 속성을 검색 할 수 없습니다.


방금 Silverlight에서 부모 요소의 DataContext에 액세스하는 또 다른 솔루션 을 게시했습니다. Binding ElementName 사용합니다.


유용한 비트와 조각들 :

코드에서 주로 수행하는 방법은 다음과 같습니다.

Binding b = new Binding();
b.RelativeSource = new RelativeSource(RelativeSourceMode.FindAncestor, this.GetType(), 1);
b.Path = new PropertyPath("MyElementThatNeedsBinding");
MyLabel.SetBinding(ContentProperty, b);

Bind Relative Source 에서이 코드를 주로 Behind 코드로 복사했습니다.

또한 MSDN 페이지는 예를 들어 설명하면 꽤 좋습니다 : RelativeSource Class


이 경우를 상상해보십시오. 높이가 항상 너비와 같기를 바라는 직사각형, 사각형이라고 가정 해 봅시다. 요소 이름을 사용하여이 작업을 수행 할 수 있습니다.

<Rectangle Fill="Red" Name="rectangle" 
                    Height="100" Stroke="Black" 
                    Canvas.Top="100" Canvas.Left="100"
                    Width="{Binding ElementName=rectangle,
                    Path=Height}"/>

그러나 위의 경우에 우리는 바인딩 객체의 이름, 즉 사각형을 나타내야합니다. 우리는 RelativeSource를 사용하여 다르게 동일한 목적을 달성 할 수 있습니다.

<Rectangle Fill="Red" Height="100" 
                   Stroke="Black" 
                   Width="{Binding RelativeSource={RelativeSource Self},
                   Path=Height}"/>

이 경우 우리는 바인딩 객체의 이름을 언급 할 의무가 없으며 높이가 변경 될 때마다 너비가 항상 높이와 같습니다.

너비의 높이를 높이의 절반으로 지정하려면 Binding 태그 확장에 변환기를 추가하면됩니다. 이제 다른 사례를 상상해 봅시다.

 <TextBlock Width="{Binding RelativeSource={RelativeSource Self},
                   Path=Parent.ActualWidth}"/>

위의 경우는이 요소가 Parent라는 속성을 보유하고 있으므로 주어진 요소의 특정 속성을 직접 부모 요소 중 하나에 연결하는 데 사용됩니다. 이것에 의해, FindAncestor 인 상대 소스 모드가됩니다.


WPF에서 RelativeSource 바인딩은 다음 세 가지 properties 을 설정합니다.

1. 모드 : 다음과 같은 네 가지 값을 가질 수있는 enum 입니다.

에이. PreviousData ( value=0 ) : property 의 이전 값을 바인드 된 값에 할당합니다.

비. TemplatedParent ( value=1 ) : 컨트롤의 templates 을 정의하고 컨트롤의 값 / 속성에 바인딩하려는 경우 사용됩니다.

예를 들어 ControlTemplate 정의하십시오.

  <ControlTemplate>
        <CheckBox IsChecked="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Value, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />
 </ControlTemplate>

기음. 자아 ( value=2 ) : self 또는 selfproperty 으로부터 구속하고자 할 때.

예 : CheckBox 에서 Command 을 설정하는 동안 checkbox 상태를 CommandParameter 로 보냅니다 .

<CheckBox ...... CommandParameter="{Binding RelativeSource={RelativeSource Self},Path=IsChecked}" />

디. FindAncestor ( value=3 ) : Visual Tree 의 상위 control 에서 바인딩 할 때.

예 : header checkbox 이 선택되어 있으면 gridrecords 가있는 경우 checkbox 을 바인딩합니다 .

<CheckBox IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}, Path=DataContext.IsHeaderChecked, Mode=TwoWay}" />

2. AncestorType : 모드가 FindAncestor 인 경우 조상의 유형을 정의하십시오

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid}}

3. AncestorLevel : 모드가 FindAncestor 경우 조상의 레벨 ( visual tree 에 동일한 유형의 상위 유형이있는 경우)

RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type iDP:XamDataGrid, AncestorLevel=1}}

위에는 RelativeSource binding 모든 유스 케이스가 있습니다.

다음은 참조 링크 입니다.


Binding RelativeSource={
    RelativeSource Mode=FindAncestor, AncestorType={x:Type ItemType}
}
...

RelativeSource 의 기본 특성은 Mode 속성입니다. 유효한 값의 전체 집합이 여기에 나와 있습니다 ( MSDN에서 ).

  • PreviousData 표시되는 데이터 항목 목록에서 이전 데이터 항목 (데이터 항목이 포함 된 컨트롤이 아님)을 바인딩 할 수 있습니다.

  • TemplatedParent 데이터 바인딩 요소가있는 템플릿이 적용되는 요소를 나타냅니다. 이는 TemplateBindingExtension을 설정하는 것과 유사하며 Binding이 템플릿 내에있는 경우에만 적용 할 수 있습니다.

  • Self 바인딩을 설정중인 요소를 참조하고 해당 요소의 한 속성을 동일한 요소의 다른 속성에 바인딩 할 수 있습니다.

  • FindAncestor 데이터 바인딩 요소의 부모 체인에있는 조상을 나타냅니다. 이 메소드를 사용하여 특정 유형 또는 그 서브 클래스의 조상에 바인드 할 수 있습니다. AncestorType 및 / 또는 AncestorLevel을 지정하려는 경우 사용하는 모드입니다.





relativesource