是否有一种更清晰的方法将属性绑定到所有者的DataContext?

时间:2010-04-27 17:54:08

标签: c# wpf data-binding binding 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>

这很有效,但Slot Binding的丑陋让我烦恼。这是必需的,因为GroupPrototypeSlotControl具有GroupPrototypeViewModel作为其DataContext。如果我只是使用{Binding SelectedSlot},它会尝试在'child'ViewModel上解析它,它会失败。我通过显式查看父控件的DataContext来解决这个问题。有没有更简洁的方法来进行这种类型的绑定?


编辑:我找到了一种更清晰的方法来解决我的问题,尽管它仍然像一个黑客。我修改了GroupPrototypeSlotControl,使其具有顶级LayoutRoot(在本例中为StackPanel),然后将LayoutRoot的DataContext设置为ViewModel,而不是设置整个控件的DataContext。这允许我使用{Binding SelectedSlot}语法,我使用控件(因为控件仍然具有父DataContext),代价是略微增加了控件的复杂性。通常,这可能是自定义控件的更好模式,因为控件的使用者期望{Binding}解析为其父DataContext(如果未明确指定)。

1 个答案:

答案 0 :(得分:1)

稍微清洁(较短)的方法是在ElementName中使用Binding,如下所示:

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