2013-03-28 55 views
4

这两个元素所在的用户控件具有名为ColumnTypes的属性。将数据绑定到XAML中的父数据环境

这些元素中的每一个都指向主要数据上下文相同的表达式,但第一个是而不是工作,而后者是。

你有什么想法如何调查?

<DataGrid x:Name="DataGrid" AutoGenerateColumns="False" ItemsSource="{Binding Table}" > 
    <DataGrid.Columns> 
      <DataGridComboBoxColumn Header="Type" > 
       <DataGridComboBoxColumn.ItemsSource> 
        <Binding Path="DataContext.GetColumnTypes" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" /> 
       </DataGridComboBoxColumn.ItemsSource> 
      </DataGridComboBoxColumn> 
    </DataGrid.Columns> 
</DataGrid> 
<ComboBox Grid.Row="1"> 
    <ComboBox.ItemsSource> 
     <Binding Path="DataContext.GetColumnTypes" RelativeSource="{RelativeSource FindAncestor, AncestorType={x:Type UserControl}}" /> 
    </ComboBox.ItemsSource> 
</ComboBox> 

System.Windows.Data错误:4:不能用于与参照结合找到源 '的RelativeSource FindAncestor,AncestorType =' System.Windows.Controls.UserControl” ,AncestorLevel ='1''。 BindingExpression:路径= DataContext.GetColumnTypes;的DataItem = NULL;目标元素是'DataGridComboBoxColumn'(HashCode = 53813616);目标属性是'ItemsSource'(类型'IEnumerable')

回答

8

这是DataGridComboBoxColumn的已知限制。

你可以看到on MSDN什么样的东西可以绑定到它的ItemsSource属性。一个普通的财产不是其中之一,所以你的情况不会奏效。

实现你想要的东西的另一种方法是制作一个DataGridTemplateColumn其中包含一个ComboBox

在你的情况,将是这个样子:

<DataGrid.Columns> 
    <DataGridTemplateColumn Header="Type"> 
     <DataGridTemplateColumn.CellTemplate> 
      <DataTemplate> 
       <ComboBox ItemsSource="{Binding DataContext.GetColumnTypes, 
         RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" /> 
      </DataTemplate> 
     </DataGridTemplateColumn.CellTemplate> 
    </DataGridTemplateColumn> 
</DataGrid.Columns> 
+0

谢谢你这个答案。从我的亵渎神灵这种事情的不可预测性,我仍然感到困惑。它真的是wpf开发者的常识吗?有很多这样的事情吗? – nicolas

+0

很高兴帮助。有些事情在WPF中有点奇怪,是的。通常在Stackoverflow上可以找到很好的答案。它绝对是与Winforms完全不同的。 –

3

DataGridColumn不在于DataGrid的Visual Tree因此它位于can't inherit its DataContext。但有一些解决方法,即你可以明确地提供DataContext到你的DataGridColumns,其详细信息可以在Provide DataContext to DataGrid Columns找到。

此外,我个人喜欢这里描述的方法 - Inheriting parent DataContext using Freezable继承使用Freezable类。

first link

代码的情况下,链接不会在今后的工作中 -

中添加这是你的App.xaml.cs in App() constructor -

FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn)); 
FrameworkElement.DataContextProperty.OverrideMetadata (typeof(DataGrid), 
new FrameworkPropertyMetadata 
    (null, FrameworkPropertyMetadataOptions.Inherits, 
    new PropertyChangedCallback(OnDataContextChanged))); 

的OnDataContextChanged回调只是从DataGrid中的DataContext转发到其列:

public static void OnDataContextChanged (DependencyObject d, 
              DependencyPropertyChangedEventArgs e) 
{ 
    DataGrid grid = d as DataGrid ; 
    if (grid != null ) 
    {     
     foreach (DataGridColumn col in grid.Columns) 
     { 
      col.SetValue (FrameworkElement.DataContextProperty, e.NewValue); 
     } 
    } 
}