1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【WPF】DataGrid 行クリックを制御する

Posted at

【WPF】DataGrid 行をクリックしたときに ViewModel のコマンドを確実に発火させる方法

── Behavior + InvokeCommandAction で MVVM を崩さず実現する

WPF の DataGrid を使っていると、次のような要望がよくあります。

  • 行をクリックするだけで ViewModel のメソッドを実行したい
  • 同じ行を連続クリックしても毎回発火してほしい
  • コードビハインドには書きたくない(MVVMを崩したくない)

しかし、SelectionChanged では 同じ行を連続クリックしても発火しない ので条件を満たせません。

そこで本記事では、

  • 左クリックのたびに ViewModel のコマンドを確実に実行する方法

を Behavior / EventTrigger / InvokeCommandAction で実装していきます。

🎯 完成イメージ

  • DataGrid の行を左クリックすると ViewModel の RowClickCommand が呼ばれる
  • その行のデータ(EmployeeDModel など)がコマンドパラメータとして渡る
  • コードビハインドは書かない

🔧 必要ライブラリ

  • NuGet から追加: Microsoft.Xaml.Behaviors.Wpf

🧩 XAML の先頭に必要な名前空間

まずこの 1 行目〜6 行目がないと Behaviors が使えません。役割も記載します。

<Window x:Class="MvvmSample.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:MvvmSample"
        xmlns:i="http://schemas.microsoft.com/xaml/behaviors"
        Title="MainWindow" Height="450" Width="800">
宣言 役割
xmlns WPF 標準コントロール(Button, Grid 等)を使う
xmlns:x x:Class / x:Name など XAML 文法用
xmlns:local 自作クラス(UserControl等)を XAMLで使うとき
xmlns:i Interaction.Triggers / InvokeCommandAction を使うため

今回の記事で重要なのは 4 行目の xmlns:i。これを入れないと InvokeCommandAction が使えません。

🧱 DataGrid に左クリックコマンドを追加する XAML

<DataGrid x:Name="EmployeeGrid"
          ItemsSource="{Binding Items}"
          SelectedItem="{Binding SelectedEmployee}"
          AutoGenerateColumns="True"
          IsReadOnly="True">

    <i:Interaction.Triggers>
        <!-- 左クリックでコマンドを実行 -->
        <i:EventTrigger EventName="MouseLeftButtonUp">
            <i:InvokeCommandAction
                Command="{Binding RowClickCommand}"
                CommandParameter="{Binding SelectedItem, ElementName=EmployeeGrid}" />
        </i:EventTrigger>
    </i:Interaction.Triggers>

</DataGrid>

🔍 動作の流れ

クリック操作 何が起きるか
行を左クリック MouseLeftButtonUp が発生
EventTrigger が拾う InvokeCommandAction を起動
InvokeCommandAction が ViewModel の RowClickCommand を実行 その時の SelectedItem がコマンドの引数になる

ポイント

要素 重要な点
EventName="MouseLeftButtonUp" 「クリック後に実行」なので誤作動が少ない。必要なら PreviewMouseLeftButtonDown に変更してセルがハンドルする前に拾ってもよい。
Command="{Binding RowClickCommand}" DataGrid の DataContext(ViewModel)のコマンド。
CommandParameter="{Binding SelectedItem, ElementName=EmployeeGrid}" クリック時の行データをそのまま渡す。

🧠 ViewModel 側(CommunityToolkit.Mvvm 使用)

[RelayCommand]
private void RowClick(EmployeeDModel? row)
{
    if (row == null)
    {
        return;
    }

    MessageBox.Show($"{row.Name} がクリックされました。");
}
  • [RelayCommand] によって RowClickCommand が自動生成。
  • パラメータ row には DataGrid の SelectedItem が渡ってくる。

⚡ この方法のメリット

項目 理由
同じ行の連続クリックでも毎回発火 EventTrigger を直接クリックにバインドしているため
コードビハインド不要 MVVM を壊さない
DataGrid のどのセルをクリックしても動作 セルイベントを意識しなくてよい
可読性・拡張性が高い Trigger / Action が UI 側の振る舞いとして完結している

❌ よくある失敗原因

現象 原因
メソッドが呼ばれない Microsoft.Xaml.Behaviors.Wpf が未インストール
Binding エラーで null が届く x:Name="EmployeeGrid" が付いていない
コンパイルエラー xmlns:i="http://schemas.microsoft.com/xaml/behaviors" を宣言していない

🎉 まとめ

DataGrid のクリック処理には SelectionChanged よりも EventTrigger + InvokeCommandAction が適しています。

  • 左クリックのたびに確実にコマンド実行
  • 連続クリックでも毎回発火
  • MVVM を崩さない
  • 実装がシンプル

✨ 次に拡張したくなったら…

今の構成に追加するだけで実現できます。

やりたいこと 追加するもの
ダブルクリックで編集画面を出したい EventName="MouseDoubleClick"
右クリック選択をしたい ビヘイビア(PreviewMouseRightButtonDown
Ctrl + クリックで複数選択 ビヘイビア

以上、「WPF DataGrid 行の左クリック挙動を MVVM で確実に処理する方法」でした。質問・改善案・応用パターンの相談があれば気軽にコメントください!この記事が開発のお役に立てば嬉しいです 🙌

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?