문제

어떻게 사용 RelativeSource WPF 바인딩은 무엇을 사용하여 다양한 사용 사례?

도움이 되었습니까?

해결책

에 바인딩하려면 다른 속에서 개체:

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

을 얻고 싶은 경우 속성에서는 상위 항목:

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

을 얻고 싶은 경우에는 숙박 시설에 템플릿 부모(그래서 당신이 할 수있는 2 가지의 방법인에서 테마 리소)

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

거나,짧은(이만 작품에 대한 OneWay 바인딩):

{TemplateBinding Path=PathToProperty}

다른 팁

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

기본 속성 RelativeSourceMode 을 제공합니다.완전한 설정의 유효한 값을 주고 있습니다(에서 MSDN):

  • PreviousData 수 바인딩하려면 이전의 데이터 항목(지 않을 제어하는 데이터가 포함된 항목)목록에서의 데이터 항목이 표시됩니다.

  • TemplatedParent 참조하는 요소는 템플릿에서(데이터 바인딩 요소가 존재하는)이 적용됩니다.이것은 비슷한 설정 TemplateBindingExtension 과는 경우에만 적용 바인딩에서는 템플릿입니다.

  • 셀프 참조하는 요소를 설정하는 바인딩을 할 수 바인딩 하나의 속성 요소를 다른 숙박 시설에 같은 요소입니다.

  • FindAncestor 말 조상도 부모의 체인 데이터 바인딩 요소입니다.당신이 사용할 수 있는 이 바인딩하는 조상에 특정 유형의 또는 그것의 하위 클래스.이 모드를 사용하려는 경우 지정 AncestorType 및/또는 AncestorLevel.

여기에 더 많은 시각적 설명의 컨텍스트에서된 이링

enter image description here

이 경우,사각형을 그리는 그 높이가 항상 그리고 그것의 폭,광장이 말하자.우리가 할 수 있을 사용하여 이를 요소는 이름

<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}"/>

는 경우 우리는지 의무의 이름을 언급하는 바인딩체 및 폭 항상 동일한 높이할 때마다 높이 변경되었습니다.

하려는 경우 매개 변수할 수 있도록 폭의 절반 높이 그런 다음 이를 수행할 수 있습을 추가하여 변환기를 바인딩 태그를 확장.자 상상이 다른 경우 지금:

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

위의 경우는 사용하는 넥타이어의 속성 지정된 요소 중 하나에 직접적인 부모들이 요소가 보유하는 시설이라고 합니다.이것은 우리들을 다른 상대 소스 모드는 FindAncestor 하나입니다.

Bechir Bejaoui 노출의 사용 사례를 RelativeSources WPF 에 여기에 자신의 문서:

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}"/>

는 경우 우리는지 의무의 이름을 언급하는 바인딩 체 및 폭 항상 동일한 높이할 때마다 높이 변경되었습니다.

하려는 경우 매개 변수할 수 있도록 폭의 절반 높이 다음 이렇게 할 수 있습을 추가하여 변환기를 바인딩 태그를 확장.자 상상이 다른 경우 지금:

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

위의 경우는 사용하는 넥타이어의 속성 지정된 요소를 하나의 그것의 직접적인 부모들이 요소를 보유하고 있는 재산 라고 부모입니다.이것은 우리들을 다른 상대 소스 모드가 이 FindAncestor 하나입니다.

  1. 모 FindAncestor

이 경우에,재산의 지정된 요소를 연결할 수 있는 하나의 그것의 부모님의 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=2AncestorLevel=1 조 이 발생합니다.음의 유형을 변경하려면 조상에서 AncestorType=국경을 AncestorType=캔버스에 무엇을 볼 발생합니다.

표시된 텍스트가 변화에 따라 조상과 유형 수준입니다.그럼 무슨 일이 일어날 경우에 조상의 수준은 적합하지 않은 조상의 유형은?이 좋은 질문입니다,나는 당신 구합니다.응답이 없는 예외가 발생하고 아무것도 아닌 것입니다 에 표시되 TextBlock 수준입니다.

  1. TemplatedParent

이 모드에서는 타이 특정 테마 리소 시설을 제공 의 통제되는 테마 리소이 적용됩니다.아 문제를 이해하기는 여기를 들어 벨

<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 일종의 짧은 손으로의 첫 번째 중 하나하지만, TemplateBinding 평가에서 컴파일에서 시간의 대비 TemplatedParent 는 평가한 후 처음 실행 시간입니다.로 할 수 있는 발언에서는 아래 그림,배경과 내용 에 적용되 내에서 버튼을 통제 템플릿입니다.

에 WPF RelativeSource 바인딩을 노출하 세 properties 을 설정:

1.모:enum 수있는 네 개의 값:

니다.PreviousData(value=0): 그것은 할당 이전 값의 property 하기 은 하나밖에 없

b.TemplatedParent(value=1): 할 수 없을 때 사용됩니다.정의 templates 의 모든 제어와 원하는 바인딩하는 값이/성 control.

예를 들어, 정의 ControlTemplate:

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

c.셀프(value=2): 때 우리가 원하는 바인딩에서 selfproperty 의 자체입니다.

예를 들어: 보내의 상태 검사 checkboxCommandParameter 설정하는 동안 CommandCheckBox

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

d.FindAncestor(value=3): 을 때에 바인딩하려서 부모로 controlVisual Tree.

예를 들어: 바인딩 checkboxrecords 는 경우 grid는 경우 header 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.

여기에 참조 링크.

는 것을 잊지 않 TemplatedParent:

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

{Binding RelativeSource={RelativeSource TemplatedParent}}

그것은 노트의 가치는 사람들을 위해 걸림돌에서 이 생각의 Silverlight:

Silverlight 제공하는 감소한 하위 집합을만,이러한 명령

내가 만들어 라이브러리를 단순화하딩 구문의 WPF 포함하여 사용하기 쉽게 만드는 RelativeSource.여기에 몇 가지 예입니다.기:

{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

참고에서'앞에'예제는 내가 사용하는 방법에 대한 바인딩하는 코드는 이미 이용하여 최적화 RelayCommand 는 마지막으로 내가 확인되지 않는 기본 부품의 WPF.지 않고는'전'예되었습니다.

몇 가지 유용한 조각:

여기에서 그것을 어떻게 대부분에 코드:

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

내가 크게에서 이것을 복사 바인딩에 상대적 근원에서 뒤에 코드.

또한,MSDN 페이지가 꽤 좋은 멀리로 예를 이동: RelativeSource 클래스

나는 그냥 게시 다른 솔루션 액세스하기 위한 매핑되는 부모의 요소에 Silverlight 있습니다.그것은 사용 Binding ElementName.

를 읽지 않았는 모든 답변을,하지만 난 그냥을 추가하려는 이 정보의 경우에는 상대적인 원본 명령의 결합니다.

을 사용할 때 상대원 Mode=FindAncestor, 바인딩처럼 되어야 합니다:

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

를 추가하지 않으면 매핑되는 경로에서 실행 시간에 그것을 검색할 수 없습니다.

이것은 예를 들어 사용이 패턴의하는 나를 위해 일 빈에서 datagrids.

<Style.Triggers>
    <DataTrigger Binding="{Binding Items.Count, RelativeSource={RelativeSource Self}}" Value="0">
        <Setter Property="Background">
            <Setter.Value>
                <VisualBrush Stretch="None">
                    <VisualBrush.Visual>
                        <TextBlock Text="We did't find any matching records for your search..." FontSize="16" FontWeight="SemiBold" Foreground="LightCoral"/>
                    </VisualBrush.Visual>
                </VisualBrush>
            </Setter.Value>
        </Setter>
    </DataTrigger>
</Style.Triggers>

는 경우 요소의 일부가 아닙니다 visual 트리,그 RelativeSource 작동 하지 않습니다.

이 경우에,당신은 필요 시 다른 기술을 개척하여 토마스 Levesque.

그는 솔루션을에서는 그의 블로그에서 [WPF]에 바인딩하는 방법을 때 데이터 매핑되는 상속되지 않습니다.고 그것은 작품을 절대적으로 훌륭하게!

지 않을 경우에는 그의 블로그가 아래로,부록 A 담 거울본 자신의 문서.

언급하지 마십시오 여기십시오 댓글을 직접 자신의 블로그에 포스트.

부록 A:울의 블로그에 포스트

이 매핑되는 숙박 시설에 WPF 은 매우 편리하기 때문에,그것은 자동으로 상속으로 모든 어린이의 요소 할당한다;따라서 당신은 설정할 필요가 없이 그것을 다시 각 요소에 대해 당신이 원하는 바인딩.그러나 어떤 경우에 매핑되지 않은 액세스 할 수 있습니다:그것은 발생 요소에 대한되지 않는 부분의 시각적 또는 논리적인 나무입니다.그것은 매우 어려울 수 있습니다 그 다음에 바인딩하는 속에서 이러한 요소...

을 설명하자는 간단한 예제:우리의 목록을 표시하려면 제품에 DataGrid.에서 그리드,우리가 할 수 있 표시하거나 가격을 숨기는 열에 기반한 가치의 ShowPrice 속성에 의해 노출된 뷰 모델.다음 방법을 사용할 수 있습니다 바인딩 가시성 의 열 ShowPrice 속성:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding ShowPrice,
                Converter={StaticResource visibilityConverter}}"/>

불행하게도,값 변경 ShowPrice 효과가 없고 열가 항상 표시되는 이유는?면 우리는 출력에서 창 Visual Studio 에서,우리는 다음 사항을 확인합니다 라인:

시스템입니다.Windows.데이터 오류가:2:을 찾을 수 없는 관 FrameworkElement 또는 frameworkcontentelement 에 대한 대상 요소입니다.BindingExpression:Path=ShowPrice;DataItem=null;대상 요소입니다'DataGridTextColumn'(차=32685253);대상 시설은'가시성'(유형'가시성')

메시지가 오히려한,그러나 의미입니다 실제로 아주 간단하다:WPF 알지 못하는 FrameworkElement 사용하를 얻을 매핑되기 때문에 열에 속하지 않은 시각적 또는 논리 나무의 DataGrid.

우리도 할 수 있습을 조정할 수 바인딩을 원하는 결과를 얻기 위해 예를 들어,설정 RelativeSource DataGrid 자체:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding DataContext.ShowPrice,
                Converter={StaticResource visibilityConverter},
                RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid}}"/>

나를 추가할 수 있습니다란 바 ShowPrice,과에 바인딩하려고 열시 공용 속성을 지정하는 요소로 이름:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding IsChecked,
                Converter={StaticResource visibilityConverter},
                ElementName=chkShowPrice}"/>

그러나 아무도 이러한 대안을 작동하는 것 같다,우리는 항상 같은 결과를 얻을...

이 시점에서,그것은 보인다는 가능한 유일한 방법 것을 변경하는 열성 코드에서 뒤에,우리는 일반적으로 선호하는 경우를 피하기 위해 사용된 이 패턴...그러나 나는 포기하지 않도록 즉시 적어도 있는 동안은 다른 옵션을 고려할😉

해결책은 우리의 문제는 실제로 아주 간단하고 활용하 Freezable 클래스입니다.기본 목적은 이 클래스의 정의가 있는 개체를 수정할 수 있고 읽기-유일한 국가이지만,흥미로운 기능은 우리의 경우에는 Freezable 개체할 수 있는 상속에 매핑되는 경우에도 그들이 시각적 또는 논리적인 나무입니다.나는 알 수 없는 정확한 메커니즘이 이를 가능하게 하는 행동,하지만 우리는 그것을 활용하여 확인 우리의 바인딩이다.

아이디어는 클래스를 만들(나는 그것 BindingProxy 한 이유는 명백하게 되는 곧)상속되는 Freezable 및 선언하는 데이터는 종속성 속성:

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.  This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data", typeof(object), typeof(BindingProxy), new UIPropertyMetadata(null));
}

우리는 할 수 있음을 선언하는 이 클래스의 인스턴스에서의 자원 DataGrid 바 데이터를 제공하는 현재 매핑되:

<DataGrid.Resources>
    <local:BindingProxy x:Key="proxy" Data="{Binding}" />
</DataGrid.Resources>

마지막 단계입니다 이를 지정하 BindingProxy 체(쉽게 액세스할 수 있으로 StaticResource)으로 원인:

<DataGridTextColumn Header="Price" Binding="{Binding Price}" IsReadOnly="False"
                Visibility="{Binding Data.ShowPrice,
                Converter={StaticResource visibilityConverter},
                Source={StaticResource proxy}}"/>

참고하는 바인딩을 경로를 붙"Data"때문에,경로가 지금 상대 BindingProxy 개체입니다.

바인딩을 지금 제대로 작동하고,열의가 제대로 표시하거나 숨겨진 기반으로 ShowPrice 을 제공합니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top