DataTemplate에서 부모 DataContext에 액세스
나는이 ListBox
뷰 모델에 자식 컬렉션에있는 바인딩을. 목록 상자 항목은 상위 ViewModel의 속성에 따라 데이터 템플릿에서 스타일이 지정됩니다.
<Style x:Key="curveSpeedNonConstantParameterCell">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=DataContext.CurveSpeedMustBeSpecified,
ElementName=someParentElementWithReferenceToRootDataContext}"
Value="True">
<Setter Property="Control.Visibility" Value="Hidden"></Setter>
</DataTrigger>
</Style.Triggers>
</Style>
다음과 같은 출력 오류가 발생합니다.
System.Windows.Data Error: 39 : BindingExpression path error:
'CurveSpeedMustBeSpecified' property not found on
'object' ''BindingListCollectionView' (HashCode=20467555)'.
BindingExpression:Path=DataContext.CurveSpeedMustBeSpecified;
DataItem='Grid' (Name='nonConstantCurveParametersGrid');
target element is 'TextBox' (Name='');
target property is 'NoTarget' (type 'Object')
따라서 바인딩 식을 변경하면 "Path=DataContext.CurrentItem.CurveSpeedMustBeSpecified"
작동하지만 부모 사용자 정의 컨트롤의 데이터 컨텍스트가 BindingListCollectionView
. 이 허용되지 않기 때문에의 속성에 대한 사용자 제어 귀속 나머지 CurrentItem
상의 BindingList
자동.
컬렉션 뷰 또는 단일 항목 인 상위 데이터 컨텍스트에 관계없이 작동하도록 스타일 내에서 바인딩 식을 지정하려면 어떻게해야합니까?
Silverlight의 상대 소스에 문제가 있습니다. 검색하고 읽은 후 추가 바인딩 라이브러리를 사용하지 않고는 적절한 솔루션을 찾지 못했습니다. 그러나 데이터 컨텍스트를 알고있는 요소를 직접 참조 하여 상위 DataContext 에 대한 액세스 권한을 얻는 또 다른 방법 이 있습니다. 그것은 사용 Binding ElementName
하고 당신이 당신의 자신의 이름을 존중하고 무거운 재사용이없는만큼, 아주 잘 작동 templates
/ styles
구성 요소에서를 :
<ItemsControl x:Name="level1Lister" ItemsSource={Binding MyLevel1List}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content={Binding MyLevel2Property}
Command={Binding ElementName=level1Lister,
Path=DataContext.MyLevel1Command}
CommandParameter={Binding MyLevel2Property}>
</Button>
<DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>
버튼을 Style
/에 넣는 경우에도 작동합니다 Template
.
<Border.Resources>
<Style x:Key="buttonStyle" TargetType="Button">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="Button">
<Button Command={Binding ElementName=level1Lister,
Path=DataContext.MyLevel1Command}
CommandParameter={Binding MyLevel2Property}>
<ContentPresenter/>
</Button>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Border.Resources>
<ItemsControl x:Name="level1Lister" ItemsSource={Binding MyLevel1List}>
<ItemsControl.ItemTemplate>
<DataTemplate>
<Button Content="{Binding MyLevel2Property}"
Style="{StaticResource buttonStyle}"/>
<DataTemplate>
<ItemsControl.ItemTemplate>
</ItemsControl>
처음 x:Names
에는 템플릿 항목 내에서 부모 요소에 액세스 할 수 없다고 생각 했지만 더 나은 솔루션을 찾지 못했기 때문에 방금 시도했으며 제대로 작동합니다.
다음 RelativeSource
과 같이 부모 요소를 찾는 데 사용할 수 있습니다.
Binding="{Binding Path=DataContext.CurveSpeedMustBeSpecified,
RelativeSource={RelativeSource AncestorType={x:Type local:YourParentElementType}}}"
See this SO question for more details about RelativeSource
.
RelativeSource vs. ElementName
These two approaches can achieve the same result,
RelativeSrouce
Binding="{Binding Path=DataContext.MyBindingProperty,
RelativeSource={RelativeSource AncestorType={x:Type Window}}}"
This method looks for a control of a type Window (in this example) in the visual tree and when it finds it you basically can access it's DataContext
using the Path=DataContext....
. The Pros about this method is that you don't need to be tied to a name and it's kind of dynamic, however, changes made to your visual tree can affect this method and possibly break it.
ElementName
Binding="{Binding Path=DataContext.MyBindingProperty, ElementName=MyMainWindow}
This method referes to a solid static Name
so as long as your scope can see it, you're fine.You should be sticking to your naming convention not to break this method of course.The approach is qute simple and all you need is to specify a Name="..."
for your Window/UserControl.
Although all three types (RelativeSource, Source, ElementName
) are capable of doing the same thing, but according to the following MSDN article, each one better be used in their own area of specialty.
How to: Specify the Binding Source
Find the brief description of each plus a link to a more details one in the table on the bottom of the page.
I was searching how to do something similar in WPF and I got this solution:
<ItemsControl ItemsSource="{Binding MyItems,Mode=OneWay}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Vertical" />
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<RadioButton
Content="{Binding}"
Command="{Binding Path=DataContext.CustomCommand,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType={x:Type ItemsControl}} }"
CommandParameter="{Binding}" />
</DataTemplate>
</ItemsControl.ItemTemplate>
I hope this works for somebody else. I have a data context which is set automatically to the ItemsControls, and this data context has two properties: MyItems
-which is a collection-, and one command 'CustomCommand'. Because of the ItemTemplate
is using a DataTemplate
, the DataContext
of upper levels is not directly accessible. Then the workaround to get the DC of the parent is use a relative path and filter by ItemsControl
type.
the issue is that a DataTemplate isn't part of an element its applied to it.
this means if you bind to the template you're binding to something that has no context.
however if you put a element inside the template then when that element is applied to the parent it gains a context and the binding then works
so this will not work
<DataTemplate >
<DataTemplate.Resources>
<CollectionViewSource x:Key="projects" Source="{Binding Projects}" >
but this works perfectly
<DataTemplate >
<GroupBox Header="Projects">
<GroupBox.Resources>
<CollectionViewSource x:Key="projects" Source="{Binding Projects}" >
because after the datatemplate is applied the groupbox is placed in the parent and will have access to its Context
so all you have to do is remove the style from the template and move it into an element in the template
note that the context for a itemscontrol is the item not the control ie ComboBoxItem for ComboBox not the ComboBox itself in which case you should use the controls ItemContainerStyle instead
참고URL : https://stackoverflow.com/questions/3404707/access-parent-datacontext-from-datatemplate
'code' 카테고리의 다른 글
Xcode 5-시뮬레이터를 전환 할 때마다“iOS 시뮬레이터가 응용 프로그램을 설치하지 못했습니다.” (0) | 2020.08.20 |
---|---|
QMessageBox를 사용하는 예 / 아니오 메시지 상자 (0) | 2020.08.20 |
ko.applyBindings를 호출 할 때“Cannot read property 'nodeType'of null”발생 (0) | 2020.08.20 |
배열의 모든 요소를 Java의 특정 값으로 초기화하는 방법 (0) | 2020.08.20 |
다른 프로필이 활성화 된 경우에도 activeByDefault 인 Maven 프로필을 활성 상태로 유지하는 방법은 무엇입니까? (0) | 2020.08.19 |