[WPF] DataGrid の スクロールバー上のダブルクリックイベントの無効化はできますか?
解決済
回答 1
投稿
- 評価
- クリップ 0
- VIEW 2,943
Prism.WPFを使用してデスクトップアプリケーションを作成しています。
DataGridのダブルクリックイベントでPrismのInvokeCommandActionを利用していますが、スクロールバー上でダブルクリックを行ってもイベントが発生してしまいます。
スクロールバー上のイベントを無効化するにはどうすれば良いでしょうか。
以下コードです。
DataGridでPersonオブジェクトを表示し、ダブルクリックするとTextBlockに選択したPersonのNameが表示するようにしています。
<Window x:Class="DataGridDoubleClick.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:DataGridDoubleClick"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True"
mc:Ignorable="d"
Title="MainWindow" Height="350" Width="525">
<Grid>
<StackPanel>
<TextBlock Text="{Binding SelectedNameString}"/>
<DataGrid ItemsSource="{Binding Persons}" Height="300">
<i:Interaction.Triggers>
<i:EventTrigger EventName="MouseDoubleClick">
<prism:InvokeCommandAction Command="{Binding DoubleClickCommand}"
CommandParameter="{Binding SelectedItem,
RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"/>
</i:EventTrigger>
</i:Interaction.Triggers>
</DataGrid>
</StackPanel>
</Grid>
</Window>
using System.Linq;
using System.Collections.ObjectModel;
using Prism.Commands;
using Prism.Mvvm;
namespace DataGridDoubleClick
{
public class MainWindowViewModel : BindableBase
{
public ObservableCollection<Person> Persons { get; } = new ObservableCollection<Person>();
#region SelectedNameStringプロパティ
private string _SelectedNameString;
public string SelectedNameString
{
get { return _SelectedNameString; }
set { SetProperty(ref _SelectedNameString, value); }
}
#endregion
public DelegateCommand<Person> DoubleClickCommand { get; }
public MainWindowViewModel()
{
Persons.AddRange(Enumerable.Range(1, 100).Select(x => new Person()
{
Id = x,
Name = "田中太郎" + x.ToString()
}));
DoubleClickCommand = new DelegateCommand<Person>(x =>
{
SelectedNameString = x.Name;
});
}
}
public class Person
{
public int Id { get; set; }
public string Name { get; set; }
}
}
-
気になる質問をクリップする
クリップした質問は、後からいつでもマイページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
クリップを取り消します
-
良い質問の評価を上げる
以下のような質問は評価を上げましょう
- 質問内容が明確
- 自分も答えを知りたい
- 質問者以外のユーザにも役立つ
評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。
質問の評価を上げたことを取り消します
-
評価を下げられる数の上限に達しました
評価を下げることができません
- 1日5回まで評価を下げられます
- 1日に1ユーザに対して2回まで評価を下げられます
質問の評価を下げる
teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。
- プログラミングに関係のない質問
- やってほしいことだけを記載した丸投げの質問
- 問題・課題が含まれていない質問
- 意図的に内容が抹消された質問
- 過去に投稿した質問と同じ内容の質問
- 広告と受け取られるような投稿
評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。
質問の評価を下げたことを取り消します
この機能は開放されていません
評価を下げる条件を満たしてません
質問の評価を下げる機能の利用条件
この機能を利用するためには、以下の事項を行う必要があります。
- 質問回答など一定の行動
-
メールアドレスの認証
メールアドレスの認証
-
質問評価に関するヘルプページの閲覧
質問評価に関するヘルプページの閲覧
checkベストアンサー
+2
提示されたコードですとスクロールバーだけでなく、カラムヘッダーや行の存在しない領域のダブルクリックでもイベントが発生すると思います。
コードビハインドで処理するなら簡単なのですが、コマンドにBindするとなるとひと手間かかると思います。
私でしたらDataGrid用に添付プロパティを設定します。
■DataGrid用添付プロパティ
public sealed class RowDoubleClickHandler : UIElement
{
public RowDoubleClickHandler(DataGrid dataGrid)
{
MouseButtonEventHandler handler = (sender, args) =>
{
var row = sender as DataGridRow;
if (row == null || row.IsSelected == false)
return;
var cmd = GetDoubleClickCommand(dataGrid);
if(cmd != null )
cmd.Execute(dataGrid.SelectedItem);
};
dataGrid.LoadingRow += (s, e) =>
{
e.Row.MouseDoubleClick += handler;
};
dataGrid.UnloadingRow += (s, e) =>
{
e.Row.MouseDoubleClick -= handler;
};
}
public static DelegateCommand<object> GetDoubleClickCommand(DataGrid dataGrid)
{
return (DelegateCommand<object>)dataGrid.GetValue(DoubleClickCommandProperty);
}
public static void SetDoubleClickCommand(DataGrid dataGrid, DelegateCommand<object> value)
{
dataGrid.SetValue(DoubleClickCommandProperty, value);
}
public static readonly DependencyProperty DoubleClickCommandProperty = DependencyProperty.RegisterAttached(
"DoubleClickCommand",
typeof(DelegateCommand<object>),
typeof(RowDoubleClickHandler),
new PropertyMetadata((o, e) =>
{
var dataGrid = o as DataGrid;
if (dataGrid != null)
new RowDoubleClickHandler(dataGrid);
}));
}
■ViewModel側コマンド
DoubleClickCommand = new DelegateCommand<object>(x =>
{
var person = x as Person;
if (person == null)
return;
});
■Xaml
<DataGrid ItemsSource="{Binding Persons}" Height="300" local:RowDoubleClickHandler.DoubleClickCommand="{Binding Path=DoubleClickCommand,Mode=OneWay}">
投稿
-
回答の評価を上げる
以下のような回答は評価を上げましょう
- 正しい回答
- わかりやすい回答
- ためになる回答
評価が高い回答ほどページの上位に表示されます。
-
回答の評価を下げる
下記のような回答は推奨されていません。
- 間違っている回答
- 質問の回答になっていない投稿
- スパムや攻撃的な表現を用いた投稿
評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。
15分調べてもわからないことは、teratailで質問しよう!
- ただいまの回答率 88.33%
- 質問をまとめることで、思考を整理して素早く解決
- テンプレート機能で、簡単に質問をまとめられる