没有指定祖先,绑定不起作用

时间:2012-04-17 13:39:46

标签: wpf binding mvvm combobox

如果我指定祖先,则下面的组合框绑定有效,但不是。如果我没有指定祖先,为什么它不起作用?

<wpftoolkit:DataGrid Grid.Row="4" Grid.Column="1" Grid.ColumnSpan="2"
                         Margin="5"
                         BorderBrush="#A6A6A6"
                         BorderThickness="1"
                         ItemsSource="{Binding DebitListing}"
                         AutoGenerateColumns="False"
                         SelectionMode="Single">
        <wpftoolkit:DataGrid.Columns>
            <wpftoolkit:DataGridComboBoxColumn
                Header="{Resx ResxName=MyBooks.Properties.Strings, Key=PartyListing_Party_Label}"
                SelectedItemBinding="{Binding Party, ValidatesOnDataErrors=True}"
                DisplayMemberPath="Name">

                <wpftoolkit:DataGridComboBoxColumn.ElementStyle>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CreditedAccounts, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                    </Style>
                </wpftoolkit:DataGridComboBoxColumn.ElementStyle>
                <wpftoolkit:DataGridComboBoxColumn.EditingElementStyle>
                    <Style TargetType="{x:Type ComboBox}">
                        <Setter Property="ItemsSource" Value="{Binding Path=DataContext.CreditedAccounts, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" />
                    </Style>
                </wpftoolkit:DataGridComboBoxColumn.EditingElementStyle>

            </wpftoolkit:DataGridComboBoxColumn>

            <wpftoolkit:DataGridTextColumn
                Header="{Resx ResxName=MyBooks.Properties.Strings, Key=PartyListing_Amount_Label}"
                Binding="{Binding Amount, ValidatesOnDataErrors=True}"/>
        </wpftoolkit:DataGrid.Columns>
    </wpftoolkit:DataGrid>

2 个答案:

答案 0 :(得分:1)

您需要引用从中获取所需DataContext的祖先的原因是因为wpftoolkit更改了其呈现的子元素上的datacontext。您会发现几乎所有ListView / DataGrid控件都是如此 - 子元素DataContext被更改为引用当前行或列所代表的集合项。如果您希望这些子元素的模板或样式中的某些内容基于控件的DataContext中的属性,则需要使用RelativeSource Ancestor来实现它。

我理解这很令人困惑,因为在基本的XAML中,子元素总是自动继承其父元素的数据上下文,但DataContext就像任何其他DependencyProperty一样,复杂的控件可以根据需要以不同的方式设置它。

如果您愿意,可以通过为您的父控件(或设置了DataContext的任何元素)提供名称来简化语法,例如x:Name='ControlRoot'。然后,当您需要返回根数据文本时,只需要执行:

Value="{Binding ElementName=ControlRoot, Path=DataContext.CreditedAccounts}"

答案 1 :(得分:0)

每次指定数据上下文时(或者在ItemsSource中指定DataGrid),绑定必须指定哪个祖先的原因,它隐藏了它的父级的数据上下文。组合框架无法访问布局层次结构中网格上方任何内容的数据上下文。要超越此限制,您可以指定要用于数据上下文的祖先。