WPF/XAML : DataGrid の行にコンテクストメニューを設定する
方針・ポイント
- EventSetter を使って DataGridRow に右マウスボタンイベント(MouseRightButtonUp)を設定する
- ContextMenu を DataGrid.Resources 内で作る
- そのイベント内で、Resources の ContextMenu を取得、設定する
ContextMenu の方もコード上で作る、右クリック時ではなく行を追加した時に ContextMenu を設定するなど、他にも様々な方法で同じことが実現できると思いますが、今回は上記の方法で行います。
右マウスボタンのイベントの方が、右クリックによるコンテクストメニューの表示よりも先に行われるようなので、最初の右クリックでメニューは表示されます。
サンプルコード
XAML
<DataGrid x:Name="MyDataGrid" AutoGenerateColumns="False"> <DataGrid.Resources> <!-- ContextMenu の作成 --> <ContextMenu x:Key="DataGridContextMenu"> <MenuItem Header="Menu 1" Click="MyDataGrid_ContextMenu1_Click"/> <MenuItem Header="Menu 2" Click="MyDataGrid_ContextMenu2_Click"/> </ContextMenu> <!-- DataGridRow に右マウスボタンイベントの設定 --> <Style TargetType="{x:Type DataGridRow}"> <EventSetter Event="MouseRightButtonUp" Handler="MyDataGrid_Row_MouseRightButtonUp"/> </Style> </DataGrid.Resources> <!-- 適当なサンプルデータ表示用の列 --> <DataGrid.Columns> <DataGridTextColumn Header="苗字" Binding="{Binding FamilyName}" Width="80"/> <DataGridTextColumn Header="名前" Binding="{Binding FirstName}" Width="80" /> </DataGrid.Columns> </DataGrid>
C#
public partial class MainWindow : Window { // 適当なサンプルデータ用のクラス public class Person { public string FirstName { get; set; } public string FamilyName { get; set; } public Person(string firstName, string familyName) { FirstName = firstName; FamilyName = familyName; } } private ObservableCollection<Person> MyDataGrid_SourceCollection; public MainWindow() { InitializeComponent(); // 適当サンプルデータを追加 MyDataGrid_SourceCollection = new ObservableCollection<Person>(); MyDataGrid_SourceCollection.Add(new Person("太郎", "山田")); MyDataGrid_SourceCollection.Add(new Person("花子", "佐藤")); MyDataGrid.ItemsSource = MyDataGrid_SourceCollection; } // DataGridRow に対する右マウスボタンイベント private void MyDataGrid_Row_MouseRightButtonUp(object sender, MouseButtonEventArgs e) { // Resources から ContextMenu を取得して設定 (sender as DataGridRow).ContextMenu = MyDataGrid.Resources["DataGridContextMenu"] as ContextMenu; } // ContextMenu の MenuItem のイベントその1 private void MyDataGrid_ContextMenu1_Click(object sender, EventArgs e) { if (MyDataGrid.SelectedItem != null) { MessageBox.Show("Menu 1 : FirstName = " +(MyDataGrid.SelectedItem as Person).FirstName); } } // ContextMenu の MenuItem のイベントその2 private void MyDataGrid_ContextMenu2_Click(object sender, EventArgs e) { if (MyDataGrid.SelectedItem != null) { MessageBox.Show("Menu 2 : FamilyName = " + (MyDataGrid.SelectedItem as Person).FamilyName); } } }