溫故知新,分流WPF的按鈕單擊和整個區域雙擊事件響應,治癒錯亂的互動應答
阿新 • • 發佈:2021-07-13
背景
在WPF客戶端專案中,遇到一個異常,一個DataGrid
表格元件中,已經存在了一個全域性的雙擊事件,還存在一個單擊按鈕,這兩個按鈕繫結的事件和作用是同一個,然後測試人員就發現,快速在單擊按鈕上單擊,就會產生誤觸事件,出現點2
次,實際上觸發了3
次的情況。
其實也很好理解,因為快速單擊兩次就同時觸發了雙擊事件嘛,所以我們需要分流按鈕單擊和整個區域雙擊事件響應,來治理這個情況。
解決方案
移除原來的雙擊事件
這裡的思路,主要是改造雙擊事件,全域性的雙擊事件是有問題的。
<i:EventTrigger EventName="MouseDoubleClick"> <i:InvokeCommandAction Command="{Binding AddCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=SelectedItem}" /> </i:EventTrigger>
我們把這段註釋掉。
監聽滑鼠左鍵按下事件
<i:EventTrigger EventName="MouseLeftButtonDown">
<command:EventToCommand
PassEventArgsToCommand="True"
Command="{Binding MouseLeftButtonDownCommand}"
/>
</i:EventTrigger>
這裡我們通過繫結的EventToCommand
方法來監聽MouseLeftButtonDown
這個動作的EventArgs
。
private MouseButtonEventArgs _mouseButtonEventArgs;
public ICommand MouseLeftButtonDownCommand
{
get
{
return new RelayCommand<MouseButtonEventArgs>((args) =>
{
_mouseButtonEventArgs = args;
});
}
}
在ViewModel裡面,我們來繫結接收來自介面的這個EventArgs
,可以暫時託管在臨時變數_mouseButtonEventArgs
響應滑鼠左鍵按下事件
<i:EventTrigger EventName="MouseLeftButtonDown">
<i:InvokeCommandAction
Command="{Binding MouseLeftButtonDown, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}}"
CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=DataGrid}, Path=SelectedItem}"
/>
</i:EventTrigger>
這裡還是老辦法,通過InvokeCommandAction
方法響應MouseLeftButtonDown
事件,並且自動把當前DataGird
的SelectedItem
帶過去。
在ViewModel裡面,我們通過MouseLeftButtonDown
來接收並且響應滑鼠左鍵按下事件。
public ICommand MouseLeftButtonDown
{
get
{
return new RelayCommand<SelectDto>((selectitem) =>
{
if (_mouseButtonEventArgs != null)
{
switch (_mouseButtonEventArgs.ClickCount)
{
case 2:
{
if (selectitem != null)
{
// TODO
}
}
break;
}
}
});
}
}
通過雙擊和單擊事件的錯開,我們成功分流了兩個互動,這下,快速單擊不會觸發雙擊了,而雙擊功能也得到了保留。
這裡根據需要,看是否需要新增繫結前的DataContext.
引數哈。