The user control into which those 2 elements live has a property called ColumnTypes.
Each of those elements refer relatively with the same expression to the main datacontext, yet the first one does not work, while the latter does.
Do you have any idea how to investigate that ?
<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 Error: 4 : Cannot find source for binding with reference 'RelativeSource FindAncestor, AncestorType='System.Windows.Controls.UserControl', AncestorLevel='1''. BindingExpression:Path=DataContext.GetColumnTypes; DataItem=null; target element is 'DataGridComboBoxColumn' (HashCode=53813616); target property is 'ItemsSource' (type 'IEnumerable')
This is a known limitation of the DataGridComboBoxColumn
.
You can see on MSDN what kind of things you can bind to its ItemsSource
property. A regular property is not one of them, so your case wont work.
A different way to achieve what you want, is to make a DataGridTemplateColumn
which contains a ComboBox
.
In your case that would look something like this:
<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>
DataGridColumn
not lies in the Visual Tree
of DataGrid hence it can't inherit its DataContext
. But there are workarounds for it ie you can explicitly supply DataContext to your DataGridColumns whose details can be found Provide DataContext to DataGrid Columns .
Also, i personally like approach described here - Inheriting parent DataContext using Freezable of inheriting using Freezable
class.
Code from first link
in case link does not work in future -
Add this in your App.xaml.cs in App() constructor
-
FrameworkElement.DataContextProperty.AddOwner(typeof(DataGridColumn));
FrameworkElement.DataContextProperty.OverrideMetadata ( typeof(DataGrid),
new FrameworkPropertyMetadata
(null, FrameworkPropertyMetadataOptions.Inherits,
new PropertyChangedCallback(OnDataContextChanged)));
The OnDataContextChanged callback simply forwards the DataContext from DataGrid to its columns:
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 );
}
}
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.