4

これら 2 つの要素が存在するユーザー コントロールには、ColumnTypes というプロパティがあります。

これらの各要素は、同じ式でメインのデータコンテキストを相対的に参照しますが、最初の要素は機能しませが、後者は機能します。

それを調査する方法はありますか?

<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:Path=DataContext.GetColumnTypes; DataItem=null; ターゲット要素は 'DataGridComboBoxColumn' (HashCode=53813616) です。ターゲット プロパティは 'ItemsSource' (タイプ 'IEnumerable') です。

4

2 に答える 2

8

これは、 の既知の制限ですDataGridComboBoxColumn

MSDNItemsSourceで、そのプロパティにバインドできるものを確認できます。通常のプロパティはそれらの1つではないため、ケースは機能しません.

目的を達成するための別の方法は、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>
于 2013-03-28T13:18:48.700 に答える
3

DataGridColumnVisual TreeDataGridにはありませんcan't inherit its DataContext。ただし、回避策があります。つまり、DataContext を DataGridColumns に明示的に提供できます。その詳細は、Provide DataContext to DataGrid Columnsで確認できます。

また、私は個人的にここで説明されているアプローチが好きです-クラスを使用して継承するFreezableを使用して親DataContextを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 コールバックは、単純に DataContext を DataGrid からその列に転送します。

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 ); 
        } 
    } 
}
于 2013-03-28T13:18:39.453 に答える