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>
주의: 알기 쉽게 하기 위해, 저는 이 명령어를MarkupExtension
clr-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
'programing' 카테고리의 다른 글
SQL Server 테이블 생성 날짜 쿼리 (0) | 2023.04.20 |
---|---|
iPhone/iOS에서 전화번호의 파란색 스타일을 제거하려면 어떻게 해야 합니까? (0) | 2023.04.20 |
OS X에서 Bash 스크립트 절대 경로 (0) | 2023.04.20 |
SSH 공용 키에 액세스하려면 어떻게 해야 하나요? (0) | 2023.04.20 |
목표-C - 문자열에서 마지막 문자 제거 (0) | 2023.04.20 |