Wpf XAML绑定到数据对象的父对象

Wpf XAML绑定到数据对象的父对象,wpf,xaml,data-binding,binding,Wpf,Xaml,Data Binding,Binding,我定义了一个网格列。父网格从ItemClass类型的ObservableCollection获取其项。ItemClass有两个属性:String Foo和bool IsEditAllowed 此列绑定到属性Foo。有一个用于编辑单元格的控件模板。我想将ItemClass.IsEditAllowed属性绑定到模板中文本框的IsEnabled属性 问题是如何约束它。这能做到吗?下面的XAML在调试跟踪中显示“找不到用于绑定引用的源” 网格将允许我通过一些“自定义”事件将ItemClass本身绑定到字

我定义了一个网格列。父网格从ItemClass类型的ObservableCollection获取其项。ItemClass有两个属性:String Foo和bool IsEditAllowed

此列绑定到属性Foo。有一个用于编辑单元格的控件模板。我想将ItemClass.IsEditAllowed属性绑定到模板中文本框的IsEnabled属性

问题是如何约束它。这能做到吗?下面的XAML在调试跟踪中显示“找不到用于绑定引用的源”

网格将允许我通过一些“自定义”事件将ItemClass本身绑定到字段,然后我可以绑定到它的任何属性。那很好,但是看起来很糟糕。但如果这是唯一的办法,那也是唯一的办法

<dxg:GridColumn
                 Header="Foo Column"
                 FieldName="Foo">
    <dxg:GridColumn.EditTemplate>
        <ControlTemplate>
            <TextBox Text="{Binding Value, Mode=TwoWay}"
                     IsEnabled="{Binding Path=IsEditAllowed, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ItemClass}, AncestorLevel=1}}" />
        </ControlTemplate>
    </dxg:GridColumn.EditTemplate>
</dxg:GridColumn>

以下是答案[1]。FindAncestor在运行时XAML树中查找祖先,而不是在任意C#对象中。它无法从绑定到的成员走到ItemClass实例。但是我们知道,在XAML树中,我们上面的某个人将我们绑定到该成员,而他绑定到ItemClass实例本身。不管那是谁,我们找到了他,然后我们得到了ItemClass

因此,让我们将调试跟踪添加到绑定中,我们将看到XAML在运行时的情况。毫无疑问,还有其他可能更聪明的方法可以做到这一点,但我碰巧在没有任何研究的情况下知道这一点

首先将其添加到XAML文件顶部的名称空间:

xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
…然后在绑定本身中添加以下内容:

diag:PresentationTraceSources.TraceLevel=High
像这样:

<TextBox Text="{Binding Value, Mode=TwoWay}"
     IsEnabled="{Binding Path=IsEditAllowed, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ItemClass}, AncestorLevel=1}, diag:PresentationTraceSources.TraceLevel=High}"
/>

有两种可能更容易设置此绑定的方法

1) 命名网格。然后,您的绑定可能看起来像这样(假设dxg:GridControl有一个名为“Items”的属性,并且您已经为该属性分配了ItemClass的实例):


您应该将您的答案作为答案发布,而不使用口语。网格的Items属性绑定到ItemsClass的许多实例的ObservableCollection。网格的每一行中都显示一个ItemsClass实例。因此,在单元格模板中,我必须绑定到Items[rowindex].IsEditAllowed,但从何处获取rowindex?抱歉,一开始我误解了ItemsClass包含ObservableCollection。您拥有的另一个潜力是DataContext。大多数/所有ItemControls将项容器上的DataContext设置为项从源集合绑定到的任何对象。没有源规范的绑定使用DataContext作为源。你能用Snoop之类的工具来查看单元格和/或行上的DataContext是什么吗?是的,我已经搞定了。一个选择是跟随视觉树。最简单的选择是,单元格的DataContext对象是一个在value属性中具有单元格值的类,并且在row属性中具有row对象——ItemClass实例。所以使用它是一个非常简单的问题。
<TextBox Text="{Binding Value, Mode=TwoWay}"
    IsEnabled="{Binding Path=RowData.Row.IsEditAllowed, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type dxg:GridCellContentPresenter}, AncestorLevel=1}}"
/>
<dxg:GridControl Name="grdItems">
    <dxg:GridControl.View>
        <dxg:TableView
            NavigationStyle="Cell"
            AllowEditing="True"
            ShowingEditor="grdItems_TableView_ShowingEditor"
            />
    </dxg:GridControl.View>
<!-- ... Much XAML ... -->
</dxg:GridControl Name="grdItems">
private void grdItems_TableView_ShowingEditor(object sender, ShowingEditorEventArgs e)
{
    e.Cancel = !(e.Row as ItemClass).IsEditAllowed;
}
<TextBox IsEnabled="{Binding Path=Items.IsEditAllowed, ElementName=MyGridControl />
<TextBox IsEnabled="{Binding Path=Items.IsEditAllowed, RelativeSource={RelativeSource AncestorType={x:Type dxg:GridControl}}}" />