简体   繁体   English

绑定到父级DataContext中的依赖项属性

[英]Bind to a Dependency Property that is in parent's DataContext

I would like to bind third column to a CollectionBindingTwo property that is within Window's DataContext and not inside DataContext of an Items from CollectionBindingOne . 我想将第三列绑定到Window的DataContext中的CollectionBindingTwo属性,而不是CollectionBindingOne中的Items的DataContext。

By defining the second collection inside <DataGrid> WPF assumes local scope or something, and points to a property within Items of ItemsSource ( CollectionBindingOne ). 通过在<DataGrid>定义第二个集合,WPF假定本地范围或某事,并指向Items of SourceSource( CollectionBindingOne )中的属性。

<DataGrid DockPanel.Dock="Top" ItemsSource="{Binding CollectionBindingOne}" AutoGenerateColumns="False">
    <DataGridTextColumn Header="One" Binding="{Binding PropOne}"/>
    <DataGridTextColumn  Header="Two" Binding="{Binding PropTwo}"/>
    <DataGridComboBoxColumn Header="Three" ItemsSource="{Binding CollectionBindingTwo}"/>
</DataGrid>

For example, this works because ComboBox is not inside a <DataGrid> : 例如,这是因为ComboBox不在<DataGrid>

<ComboBox IsEditable="True" ItemsSource="{Binding CollectionBindingTwo}"></ComboBox>

The DataGridComboBoxColumn is not a part of the Visual Tree so the usual RelativeSource/ElementName binding formats won't work. DataGridComboBoxColumn不是Visual Tree的一部分,因此通常的RelativeSource / ElementName绑定格式不起作用。 You can use a workaround by defining the ElementStyle and EditingStyle where those binding formats will work. 您可以通过定义ElementStyle和EditingStyle来使用解决方法,其中这些绑定格式将起作用。 Another option is to use a BindingProxy which I use for other spots and will save some XAML when there is no other reason to define an ElementStyle/EditingStyle. 另一种选择是使用我用于其他点的BindingProxy,并且在没有其他理由来定义ElementStyle / EditingStyle时将保存一些XAML。

This is the BindingProxy class which inherits from Freezable. 这是继承自Freezable的BindingProxy类。

public class BindingProxy : Freezable
{
    #region Overrides of Freezable

    protected override Freezable CreateInstanceCore()
    {
        return new BindingProxy();
    }

    #endregion

    public object Data
    {
        get { return (object)GetValue(DataProperty); }
        set { SetValue(DataProperty, value); }
    }

    // Using a DependencyProperty as the backing store for Data.
    // This enables animation, styling, binding, etc...
    public static readonly DependencyProperty DataProperty =
        DependencyProperty.Register("Data",
                                    typeof(object),
                                    typeof(BindingProxy),
                                    new UIPropertyMetadata(null));
}

Now your xaml looks like this: 现在你的xaml看起来像这样:

<DataGrid DockPanel.Dock="Top"
          ItemsSource="{Binding CollectionBindingOne}"
          AutoGenerateColumns="False">
    <DataGrid.Resources>
        <helper:BindingProxy x:Key="proxy"
                             Data="{Binding }" />
    </DataGrid.Resources>
    <DataGrid.Columns>
        <DataGridTextColumn Header="One"
                            Binding="{Binding PropOne}" />
        <DataGridTextColumn Header="Two"
                            Binding="{Binding PropTwo}" />
        <DataGridComboBoxColumn Header="Three" 
                                ItemsSource="{Binding Data.CollectionBindingTwo,
                                              Source={StaticResource proxy}}" />
</DataGrid>

Don't forget to declare the helper namespace import at the top of your Window/UserControl. 不要忘记在Window / UserControl的顶部声明帮助程序命名空间导入。

That's what the [RelativeSource][1] bindings are for. 这就是[RelativeSource][1]绑定的用途。 In this case you should be able to target parent data context by way of the the DataGrid's data context: 在这种情况下,您应该能够通过DataGrid的数据上下文来定位父数据上下文:

<DataGrid>
    <DataGridComboBoxColumn Header="Three" ItemsSource="{Binding  
        RelativeSource={RelativeSource AncestorType=DataGrid},
        Path=DataContext.CollectionBindingTwo}" />
</DataGrid>

An ElementName binding should also work: ElementName绑定也应该有效:

<DataGrid x:Name="dataGrid">
    <DataGridComboBoxColumn Header="Three" 
        ItemsSource="{Binding ElementName=dataGrid, Path=DataContext.CollectionBindingTwo}" />
</DataGrid>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM