从DataTemplate访问父DataContext [英] Access parent DataContext from DataTemplate
问题描述
我有一个 ListBox
,它绑定在ViewModel上的一个子集合。列表框项目根据父ViewModel上的属性设置在数据表中:
I have a ListBox
which binds to a child collection on a ViewModel. The listbox items are styled in a datatemplate based on a property on the parent 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
。这是不可接受的,因为用户控件的其余部分会自动绑定到 BindingList
上的 CurrentItem
的属性。
So if I change the the binding expression to "Path=DataContext.CurrentItem.CurveSpeedMustBeSpecified"
it works, but only as long as the datacontext of the parent user control is a BindingListCollectionView
. This is not acceptable because the rest of the user control binds to the properties of the CurrentItem
on the BindingList
automatically.
如何在样式中指定绑定表达式,以使其工作,而不管父数据上下文是集合视图还是单个项? >
How can I specify the binding expression inside the style so that it works regardless of the parent data context being a collection view or a single item?
推荐答案
我在Silverlight中的相对来源有问题。搜索和阅读后,我没有找到合适的解决方案,而不使用一些额外的Binding库。但是,这是通过直接引用您知道数据上下文的元素来获取对父DataContext 的另一种方法。它使用 Binding ElementName
并且工作得很好,只要你尊重自己的命名,并且不会在组件之间重复使用模板/样式:
I had problems with the relative source in Silverlight. After searching and reading I did not find a suitable solution without using some additional Binding library. But, here is another approach for gaining access to the parent DataContext by directly referencing an element of which you know the data context. It uses Binding ElementName
and works quite well, as long as you respect your own naming and don't have heavy reuse of templates/styles across components:
<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
/ 模板
:
This also works if you put the button into 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
的父元素无法从模板化项目中访问,但由于我没有找到更好的解决方案,我只是尝试了,它的工作正常。
At first I thought that the x:Names
of parent elements are not accessible from within a templated item, but since I found no better solution, I just tried, and it works fine.
希望这个解决方案有所帮助。
I hope this solution helps.
这篇关于从DataTemplate访问父DataContext的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!