DataGridでColumnsにDataGridTrmplateColumnを置き,表示する内容を色々とカスタマイズすることが多い。
ここでたまに困るのが,DataGridTemplateColumnの中のDataTemplate内のコントロールにアクセスするとき。
何度かつまづいたので,メモする。
ポイント
MacのFinderや,Visual Studioのソリューションエクスプローラのようなツリー風のDataGridを作成した。
その時のコードを元に,ポイントを書いていく。
DataGridTemplateColumn
以下のように書いた。今回は,TreeToggleButtonにアクセスしたい。
<DataGridTemplateColumn> <DataGridTemplateColumn.CellTemplate> <DataTemplate> <StackPanel Orientation="Horizontal"> <ToggleButton x:Name="TreeToggleButton" Style="{StaticResource TreeToggleButtonStyle}"/> <Image Source="{Binding Converter={StaticResource NodeTypeIconConverter}}" Margin="0, 0, 5, 0"/> <TextBlock Text="{Binding Path=Title}"/> </StackPanel> </DataTemplate> </DataGridTemplateColumn.CellTemplate> </DataGridTemplateColumn>
コントロールを見つける処理を作る
// 子を検索する。見つからなければ孫を検索する。 private T FindVisualChild<T>(DependencyObject reference) where T : DependencyObject { for (int i = 0; i < VisualTreeHelper.GetChildrenCount(reference); i++) { DependencyObject child = VisualTreeHelper.GetChild(reference, i); if (child != null && child is T) { return (T)child; } else { T childOfChild = FindVisualChild<T>(child); if (childOfChild != null) return childOfChild; } } return null; }
実際にどう扱うか
ToggleButtonを見つける処理を以下のようにかいた。
TreeDataGridRowクラス(DataGridRowを継承した自作クラス)で行を渡し,rowのContentPresenterからDataGridCellを取得する。cellの子要素でToggleButtonであるものを更に検索する。
private bool HittingTreeToggleButton(TreeDataGridRow row, GetDragDropPosition position) { if (row == null) return false; var contentPresenter = FindVisualChild<ContentPresenter>(row); if (!(contentPresenter.TemplatedParent is DataGridCell cell)) return false; if (!(cell.Column is DataGridTemplateColumn templateColumn)) return false; ToggleButton toggleButton = FindVisualChild<ToggleButton>(cell); if (toggleButton.Name != "TreeToggleButton") return false; if (IsMouseOnTargetRow(toggleButton, position)) return true; else return false; }
問題
cellのなかにToggleButtonが2つある場合は1つしか取得できないという問題がある。
-
-
-
- mogmo
-
-