2013-03-28 35 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); 
     } 
    } 
}