XamDataGrid に ContextMenuService.Manager をアタッチして ContextMenu を設定することで、コンテキスト メニューを表示させることができるようになります。たとえばセルのどこをクリックしてもコンテキスト メニューを表示させる場合は、以下の記事が参考になります。
今回はこれを応用させて、セルに埋め込んだ画像を左クリックしたときだけコンテキスト メニューを表示させるようにしてみましょう。実際の完成イメージです。
ビュー (MainWindow.xaml) 側
<igDP:XamDataGrid ...> <ig:ContextMenuService.Manager> <ig:ContextMenuManager OpenMode="LeftClick"> <ig:ContextMenuManager.ContextMenu> <ig:XamContextMenu Name="contextMenu" Opening="contextMenu_Opening"> <ig:XamMenuItem Header="Item1" /> <ig:XamMenuItem Header="Item2" /> <ig:XamMenuItem Header="Item3" /> </ig:XamContextMenu> </ig:ContextMenuManager.ContextMenu> </ig:ContextMenuManager> </ig:ContextMenuService.Manager> ... <igDP:XamDataGrid.FieldLayouts> <igDP:FieldLayout> <igDP:FieldLayout.Fields> <igDP:Field Name="ID" Label="ID"/> <igDP:Field Name="FamilyName" Label="FamilyName"/> <igDP:Field Name="GivenName" Label="GivenName"/> <igDP:Field Name="Menu" Label="Menu" BindingType="Unbound"> <igDP:Field.CellValuePresenterStyle> <Style TargetType="{x:Type igDP:CellValuePresenter}"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="igDP:CellValuePresenter"> <Grid> <Image Source="/Assets/BlueStar.png" Width="20" /> </Grid> </ControlTemplate> </Setter.Value> </Setter> </Style> </igDP:Field.CellValuePresenterStyle> </igDP:Field> </igDP:FieldLayout.Fields> </igDP:FieldLayout> </igDP:XamDataGrid.FieldLayouts> </igDP:XamDataGrid>
- 3 行目 : 今回は左クリックしたときにコンテキストメニューを表示させるので、OpenMode=”LeftClick” にします
- 5 行目 : XamContextMenu の Opening イベントハンドラーを追加しています。ここは冒頭で紹介した記事と同じです。
- 20 ~ 34 行目 : ☆の画像を表示させる Field の 実装をしています。
- 20 行目 : 今回は特にデータソースとバインドしないので、BindingType を UnBound としています。
- 21 ~ 22 行目 : Field の CellValuePresenterStyle プロパティに CellValuePresenter をターゲット型とした Style オブジェクトを設定します。
- 23 ~ 31 行目 : CellValuePresenter の Template プロパティに CellValuePresenter をターゲット型とした ControlTemplate オブジェクトを指定し、その実態として Image オブジェクトを置いています。
ビューのコードビハインド (MainWindow.xaml.cs) 側
XamContextMenu の Opening イベントハンドラーを実装します。
private void contextMenu_Opening(object sender, Infragistics.Controls.Menus.OpeningEventArgs e) { var clickedImage = e.GetClickedElements<Image>().Count > 0 ? e.GetClickedElements<Image>().First() : null; var clickedCellValuePresenter = e.GetClickedElements<CellValuePresenter>().FirstOrDefault(cvp => cvp.Field.Name == "Menu"); if (clickedImage == null || clickedCellValuePresenter == null) { e.Cancel = true; } }
クリックされた要素が Image オブジェクトか、CellValuePresenter がクリックされ、かつ、それが Menu 列のものか、をチェックし、少なくともどちか一方が異なる場合はイベントをキャンセルしています。こうすることで、Menu 列の Image オブジェクトがクリックされたときだけコンテキストメニューが表示されるようになります。
以上で完了です!