2010-04-27 58 views
3

我有一些代码,看起来像这样:是否有更简单的方法将属性绑定到所有者的DataContext?

<Expander Header="{Binding SelectedSlot.Name}" 
      Visibility="{Binding ShowGroupSlot, Converter={StaticResource BooleanToVisibility}}"> 
    <Controls:GroupPrototypeSlotControl Slot="{Binding DataContext.SelectedSlot, 
     RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Expander}}}" /> 
</Expander> 

这工作,但插槽绑定的丑陋困扰我。这是必需的,因为GroupPrototypeSlotControl具有GroupPrototypeViewModel作为其DataContext。如果我只是使用{Binding SelectedSlot},它会尝试在'child'ViewModel上解析它,失败。我通过明确地查看父控件的DataContext来解决这个问题。有没有更好的方法来做这种绑定?


编辑:我发现一个更清洁的方式来解决我的问题,虽然它仍然感觉像一个黑客。我修改了GroupPrototypeSlotControl,使其具有顶层LayoutRoot(在本例中为StackPanel),然后将LayoutRoot的DataContext设置为ViewModel,而不是设置整个控件的DataContext。这允许我在使用控件时使用{Binding SelectedSlot}语法(因为控件仍然具有父级DataContext),代价是略微增加了控件的复杂性。一般来说,这可能是自定义控件的更好的模式,因为如果没有明确指定控件,控件的使用者需要{Binding}来解析它们的父级DataContext。

回答

1

稍微清洁剂(短)的方法是使用ElementNameBinding这样的:

<Expander Header="{Binding SelectedSlot.Name}" 
      x:Name="expander" 
      Visibility="{Binding ShowGroupSlot, Converter={StaticResource BooleanToVisibility}}"> 
    <Controls:GroupPrototypeSlotControl Slot="{Binding DataContext.SelectedSlot, ElementName=expander}" /> 
</Expander> 
相关问题