programing

XAML의 Self/'this'에 대한 바인딩

testmans 2023. 4. 20. 20:09
반응형

XAML의 Self/'this'에 대한 바인딩

간단한 WPF/XAML 질문XAML에서는 특정 컨텍스트에서 Self/this 객체를 참조하려면 어떻게 해야 합니까?메인 창, 하나의 컨트롤, 그리고 창의 코드화된 C# 속성을 가진 매우 기본적인 앱에서는 컨트롤 속성을 창의 핸드 코드 속성에 바인딩하고 싶습니다.

코드에서는 매우 간단합니다.Windows의 컨스트럭터에서 다음과 같이 추가했습니다.

Binding bind = new Binding();
bind.Source = this;
bind.Path = new PropertyPath("ButtonWidth");
button1.SetBinding(WidthProperty, bind);

물론 ButtonWidth라는 속성과 button1이라는 컨트롤이 있습니다.XAML에서 이 작업을 수행하는 방법을 알 수 없습니다.다음 예시와 같은 다양한 시도는 효과가 없습니다.

<Button x:Name="button1" Width="{Binding Source=Self Path=ButtonWidth}"/>

<Button x:Name="button1" Width="{Binding RelativeSource={RelativeSource Self} Path=ButtonWidth}"/> 

기타

감사해요.

먼저 바인딩의 RelativeSource와 경로 사이에 콤마를 사용합니다.

<Button x:Name="button1" Width="{Binding RelativeSource={RelativeSource Self}, 
                                Path=ButtonWidth}"/> 

다음으로 RelativeSource가 버튼에 바인드됩니다.버튼에 ButtonWidth라는 속성이 없습니다.부모 통제하에 묶어야 할 것 같아요

이 Relative Source 바인딩을 시험해 보겠습니다.

<Button x:Name="button1" Width="{Binding RelativeSource=
    {RelativeSource FindAncestor, AncestorType={x:Type YourNamespace:YourParentControl}}, 
    Path=ButtonWidth}"/> 

당신이 찾고 있는 것은 다음과 같습니다.

<Window x:Class = "blah blah all the regular stuff"

DataContext="{Binding RelativeSource={RelativeSource Self}}"

>

Relative Source 등의 처리를 회피하는 방법 중 하나는 루트 XAML 요소에 이름을 붙이는 것입니다.

<Window x:Class="TestApp2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    x:Name="_this"
    >
    <Grid>
        <Button x:Name="button" Width="{Binding ElementName=_this,Path=ButtonWidth}" />
    </Grid>
</Window>

DataContext를 설정하려면 다음 작업을 수행할 수도 있습니다.

<Window x:Class="TestApp2.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525"
    x:Name="_this"
    >
    <Grid DataContext="{Binding ElementName=_this}">        
        <Button x:Name="button" Width="{Binding Path=ButtonWidth}" />
    </Grid>
</Window>

Relative Source 바인딩의 모든 복잡성을 기억하지 않아도 되는 좋은 트릭이라고 생각합니다.

루트 요소의 이름을 지정할 때 문제는 프로젝트의 모든 루트에 대해 동일한 이름(즉, "_this", "Root" 등)을 사용하는 습관이 생기면 중첩된 템플릿의 지연 바인딩이 잘못된 요소에 액세스할 수 있다는 것입니다.그 이유는,{Binding} ElementName=...에서 사용됩니다.Template이름은 실행 시 위쪽으로 이동함으로써 해결됩니다.NameScope첫 번째 일치가 발견될 때까지 트리를 설정합니다.

Clint의 솔루션은 루트 요소의 이름을 붙이는 것을 피하지만 루트 요소를 독자적인 것으로 설정합니다.DataContext예를 들어 데이터에 DataContext가 필요한 경우에는 옵션이 아닐 수 있습니다.또한 요소에 대한 액세스를 제공하기 위한 목적으로 요소에 다른 바인딩을 도입하는 것은 다소 어려운 것으로 보입니다.나중에 액세스가 필요 없게 되면{Binding}접속에 대한 책임은 타깃과 바인딩에 있습니다.

따라서 XAML 루트 요소에 이름을 붙이지 않고 액세스하기 위한 간단한 마크업 확장을 다음에 나타냅니다.

using System.Xaml;
using System.Windows.Markup;

public sealed class XamlRootExtension : MarkupExtension
{
    public override Object ProvideValue(IServiceProvider sp)
    {
        var rop = sp.GetService(typeof(IRootObjectProvider)) as IRootObjectProvider;
        return rop == null ? null : rop.RootObject;
    }
};

XAML:

<Window x:Class="MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:global="clr-namespace:">

    <TextBlock Text="{Binding Source={global:XamlRoot},Mode=OneTime}" />

</Window>

주의: 알기 쉽게 하기 위해, 저는 이 명령어를MarkupExtensionclr-namespace에일리어스(여기서 나타내는 바와 같이)는, 실제로 에 액세스 하기 위해서 기능합니다.global::네임스페이스(VS2013 설계자가 불평하는 것 같긴 하지만)

결과:

여기에 이미지 설명 입력
콘텐츠가 자신에게 바인딩된 창입니다.


n.b.

안타깝게도 루트 요소의 이름을 "ElementName="로 지정했습니다.UWP에서는 {RelativeSource Self}가 지원되지 않기 때문에 UWP에서는 "만이 유일한 방법인 것 같습니다.

이상하게도, 이것은 이름이 레이아웃에 겹쳐져 있을 때에도 여전히 작동합니다.

<UserControl x:Class="Path.MyClass" x:Name="internalName">
   <Border Background={Binding Path=Background, ElementName=internalName}" ...

그리고나서

<Page>
   <local:MyClass x:Name=externalName />

</Page>

BTW, Windows 10 에서는, 같은 레이아웃내의 다른 요소에 같은 내부명이 사용되고 있는 에러(Windows 8.1 에 표시)가 수정되었습니다.

그래도 {RelativeSource Self}이(가) 더 논리적이고 안전한 것 같기 때문에 사용하는 것이 좋습니다.

언급URL : https://stackoverflow.com/questions/3837755/binding-to-self-this-in-xaml

반응형