質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

Q&A

解決済

1回答

7866閲覧

【C#】【WPF】DataGridの明細上でダブルクリックしたかどうかを検知したい

OXamarin

総合スコア59

C#

C#はマルチパラダイムプログラミング言語の1つで、命令形・宣言型・関数型・ジェネリック型・コンポーネント指向・オブジェクティブ指向のプログラミング開発すべてに対応しています。

WPF

Windows Presentation Foundation (WPF) は、魅力的な外観のユーザー エクスペリエンスを持つ Windows クライアント アプリケーションを作成するための次世代プレゼンテーション システムです

0グッド

0クリップ

投稿2019/08/11 05:32

編集2019/08/11 08:38

##前提
環境:VS2019
言語:C# WPF
フレームワーク:MVVM

##悩んでいる事
DataGridをダブルクリックすると、選択中の明細を開くようにしています。
イメージ説明

ただし、選択状態にしておいてヘッダーやスクロールバー、または条件を絞り込んだ状態で明細のない箇所など(つまりはDataGridのコントロールの上ならどこでも)をダブルクリックしても同様に選択したファイルが開いてしまいます。

これに対して、どちらかの対策をとりたいと考えていますが分かりません。
① 明細にフォーカスがあたっている場合にだけダブルクリックのイベントが発火するようにする
(もしくは、ダブルクリックのイベントが発火は許容するとして、明細にフォーカスが当たっている事が検知できればよい)

② 明細以外の箇所をクリックすると、SelectedIndex = -1 とする

できるのであれば、①のように解決したいと思っていますが、実装可能でしょうか?

--追記---
これまでは、以下のようなビヘイビア(?)を使用して、ダブルクリックを検知してVMのコマンドを実行していました。

C#

1public class MouseDoubleClick 2{ 3 #region 依存関係プロパティ 4 public static DependencyProperty CommandProperty = 5 DependencyProperty.RegisterAttached("Command", 6 typeof(ICommand), 7 typeof(MouseDoubleClick), 8 new UIPropertyMetadata(CommandChanged)); 9 public static DependencyProperty CommandParameterProperty = 10 DependencyProperty.RegisterAttached("CommandParameter", 11 typeof(object), 12 typeof(MouseDoubleClick), 13 new UIPropertyMetadata(null)); 14 #endregion 15 16 #region イベントハンドラ 17 /// <summary> 18 /// 19 /// </summary> 20 /// <param name="sender"></param> 21 /// <param name="e"></param> 22 private static void OnMouseLeftDoubleClick(object sender, MouseButtonEventArgs e) 23 { 24 if (e.ChangedButton != MouseButton.Left) return; 25 26 var control = sender as Control; 27 var command = (ICommand)control.GetValue(CommandProperty); 28 var commandParameter = control.GetValue(CommandParameterProperty); 29 command.Execute(commandParameter); 30 } 31 #endregion 32 33 #region メソッド 34 /// <summary> 35 /// 36 /// </summary> 37 /// <param name="target"></param> 38 /// <param name="value"></param> 39 public static void SetCommand(DependencyObject target, ICommand value) 40 { 41 target.SetValue(CommandProperty, value); 42 } 43 /// <summary> 44 /// 45 /// </summary> 46 /// <param name="target"></param> 47 /// <param name="value"></param> 48 public static void SetCommandParameter(DependencyObject target, object value) 49 { 50 target.SetValue(CommandParameterProperty, value); 51 } 52 /// <summary> 53 /// 54 /// </summary> 55 /// <param name="target"></param> 56 /// <returns></returns> 57 public static object GetCommandParameter(DependencyObject target) 58 { 59 return target.GetValue(CommandParameterProperty); 60 } 61 /// <summary> 62 /// 63 /// </summary> 64 /// <param name="target"></param> 65 /// <param name="e"></param> 66 private static void CommandChanged(DependencyObject target, DependencyPropertyChangedEventArgs e) 67 { 68 var control = target as Control; 69 if (control != null) 70 { 71 if ((e.NewValue != null) && (e.OldValue == null)) 72 { 73 control.MouseDoubleClick += OnMouseLeftDoubleClick; 74 } 75 else if ((e.NewValue == null) && (e.OldValue != null)) 76 { 77 control.MouseDoubleClick -= OnMouseLeftDoubleClick; 78 } 79 } 80 } 81 #endregion 82}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

おそらく何らかの方法でDataGrid上でのダブルクリックを判定していると思うのですが、こちらではなくDataGridRow上で判定してはいかがでしょうか。

DataGridはItemsSourceにコレクションをバインドすると、そのコレクションの要素の数だけ「DataGridRow」というコントロールを生成します。こちらのコントロールのイベントをハンドリングすることで、特定の行で発生したイベントを処理することが可能です。

DataGridRowへのイベントの登録は、DataGrid.ItemContainerStyleプロパティでDataGridRowのスタイルを定義することで行います。スタイルへのイベント登録はこちらなどが参考になると思います。EventSetter Class

またDataGridに限らず、ItemsControl系をカスタムするのであれば、こちらの記事が非常に参考になります。ItemsControl 攻略 ~ 外観のカスタマイズ

投稿2019/08/11 06:07

Gurz1019_MP

総合スコア196

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

OXamarin

2019/08/11 08:36

回答ありがとうございます! 早速ためしてみて、以下の様に書けばよいのだとわかりました。 <DataGrid.RowStyle> <Style TargetType="DataGridRow"> <EventSetter Event="MouseDoubleClick" Handler="EventSetter_OnMouseDoubleClick" /> </Style> </DataGrid.RowStyle> 加えて質問なのですが、EventSetterをVM側で実行したいのですが可能でしょうか? ダブルクリック時に開こうとしているファイルが存在していない場合、存在しません、という旨のメッセージをMaterialDesignのSnackbar というものを使用して出力しています。 このSnackbarというのをDIによるインスタンス生成を行っており、 VMには注入していますがコードビハインドにないのでVMで実行したいと思っています。
OXamarin

2019/08/11 08:40

追記させていただきました方法で、左ボタンのダブルクリックを検知して、VMのコマンドを実行していました。
Gurz1019_MP

2019/08/11 08:54

なるほど、DataGridにはより適切なプロパティがあったようですね。失礼しました。 質問の件ですが、添付プロパティを利用することでスタイルにTriggerやbehaviorを設定するテクニックがあるようです。https://blog.okazuki.jp/entry/2016/07/19/192918(WPFのBehaviorをStyleで使う方法) これを使えば、TriggerにInvokeCommandActionを設定してVMのコマンドが呼び出せると思います。
OXamarin

2019/08/11 10:19

こういうイメージなのかと思いましたがコマンドが実行されないですね。 もう少し調べてみます。 <DataGrid.RowStyle> <Style TargetType="DataGridRow"> <Setter Property="b:StyleBehaviorCollection.StyleBehaviors"> <Setter.Value> <b:StyleBehaviorCollection> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseDoubleClick"> <i:InvokeCommandAction Command="{Binding FileListDoubleClickCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </b:StyleBehaviorCollection> </Setter.Value> </Setter> </Style> </DataGrid.RowStyle>
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問