PR

【C#】【WPF】DataGridから親のDataContextを取得する

C#

DataGridは、ItemsSourceにバインドしたリスト(コレクション)を一覧表示してくれるのでなにかと重宝します。

しかし、DataGridから同じ親DataContextの別の要素を参照するにはノウハウが必要なので紹介します。

やりたいこと

DataGridのヘッダにチェックボックスを付けて、全選択・解除が出来るリストを作りたいと思います。

もちろん、一覧のチェックをON/OFFしたら、ヘッダのチェックも変化するようにします。

問題

DataGridは、基本的にはItemsSourceで指定したコレクションの内容のみ参照します。

ヘッダのチェックボックスは、一覧のチェックボックスに対して処理を行うものなのでコレクションとは分けて定義することになります。
ざっくりと図解すると以下のような感じ。

ヘッダのチェックボックスには、全選択・解除処理をバインドしたいのですが、そのままでは参照することが出来ません。

親のDataContextを取得する

ItemsSourceにバインドしたコレクションの親要素を取得できれば解決できそうだということは想像できるかと思います。

では、どうやって親要素を取得するのか。

RelativeSource

というものを使います。

サンプルコードは以下です。
赤いマーカーとアンダーラインの部分がポイントとなります。

<c:CustomDataGrid
    ItemsSource="{Binding InvoiceDatas,
                  Mode=TwoWay,
                  UpdateSourceTrigger=PropertyChanged}"
    AutoGenerateColumns="False"
    Style="{StaticResource DataGridStyle}">

    <c:CustomDataGrid.Columns>
        <DataGridCheckBoxColumn
            Width="30"
            Binding="{Binding IsCheck,
                      Mode=TwoWay,
                      UpdateSourceTrigger=PropertyChanged}">
            <DataGridCheckBoxColumn.Header>
                <CheckBox
                    DataContext="{Binding RelativeSource=
                        {RelativeSource
                            AncestorType={x:Type DataGrid}},
                            Path=DataContext}"
                    IsChecked="{Binding IsSelectAll,
                                UpdateSourceTrigger=PropertyChanged}"
                    Command="{Binding AllCheckChangeCommand}"
                    Style="{StaticResource ListItemCheckBoxStyle}"/>
            </DataGridCheckBoxColumn.Header>
            <DataGridCheckBoxColumn.ElementStyle>
                <Style
                    TargetType="CheckBox"
                    BasedOn="{StaticResource ListItemCheckBoxStyle}">
                    <Setter
                        Property="Command"
                        Value="{Binding CheckChangeCommand}"/>
                </Style>
            </DataGridCheckBoxColumn.ElementStyle>
            <DataGridCheckBoxColumn.EditingElementStyle>
                <Style
                    TargetType="CheckBox"
                    BasedOn="{StaticResource ListItemCheckBoxStyle}">
                    <Setter
                        Property="Command"
                        Value="{Binding CheckChangeCommand}"/>
                </Style>
            </DataGridCheckBoxColumn.EditingElementStyle>
        </DataGridCheckBoxColumn>

 :
 省略
 :

</c:CustomDataGrid>

RelativeSource

RelativeSourceの相対的な位置関係にある要素を参照しプロパティをバインドすることが出来ます。

AncestorType

上位要素の型を指定します。

先ほどのサンプルコードでは、DataGridを指定していました。

AncestorType={x:Type DataGrid}

AncestorLevel

何番目に見つかった要素を参照するかを指定します。

StackPanelなどネスト構造になっている場合に指定します。

相対的な位置関係で参照するため、内側の要素から1となる点に注意が必要です。

AncestorLevel=1

Path

参照する要素のどのプロパティを取得するのかを指定します。

Path=DataContext

最後に

DataGridは奥が深いコントロールです。

ぜひ使いこなしましょう。

コメント

タイトルとURLをコピーしました