2017-07-29 40 views
1

從生產應用程序中,我們注意到我們的WPF按鈕通過快速雙擊觸發ICommand.Execute方法兩次。WPF的命令在快速雙擊上觸發兩次

現在,在每個命令中,應用程序都會覆蓋全屏幕微調器動畫,從而阻止與應用程序的進一步交互。

This github回購包含問題的簡約回購。需要注意的是:

  • 時,按鈕的命令觸發時,「IsBusy」標誌被設置爲true
  • 作爲結果,BusyIndi​​cator控件覆蓋將顯示
  • 作爲結果,該按鈕不能再壓直到後300毫秒

然而,特別是在較慢的計算機上,當快速雙擊(真快,如遊戲,快即是),可兩次開火命令沒有BusyIndi​​cator控件阻止第二個電話(這可以如果輸出在o之後顯示2個「點擊」行,可以看到另一個)。

這對我來說是意想不到的行爲,因爲IsBusy標誌立即在UI線程上設置爲true。 第二次點擊能夠通過嗎? 我會希望IsBusy綁定顯示UI線程上的覆蓋,阻止任何進一步的交互?

GitHub的樣品還包括2個解決方法:

  1. 使用ICommand.CanExecute阻止使用PreviewMouseDown防止雙擊

我想了解執行處理

  • 問題是什麼。 你更喜歡什麼樣的解決方法?

  • 回答

    1

    診斷

    這只是我的猜測,而不是固體,並確認信息,但似乎當您單擊鼠標按鈕,命中測試立即完成,但所有的鼠標相關的事件僅安排被提出(使用Dispatcher我想)。重要的是,單擊的控件在點擊發生時確定,而不是在完成前一次點擊(包括可能遵循的所有UI更改)後才確定。

    所以你的情況,即使實際顯示在顯示BusyIndicator覆蓋(從而阻塞)的Button,如果你設法單擊該BusyIndicator前的第二次先點擊結果(這不會立即發生),則Button上的點擊事件將被調度(將在BusyIndicator顯示之後發生),導致命令被再次執行,即使此時BusyIndicator可能會阻止Button

    解決方案

    如果你的目標是防止,而前一個仍在執行的不二之選命令執行,使Command.CanExecute結果取決於IsBusy標誌的狀態。此外,我甚至不稱之爲解決方法,而是正確的設計

    你在這裏面臨的是一個明確的例子,你爲什麼不應該讓你的業務邏輯依賴於UI。首先,因爲渲染很大程度上取決於機器的處理能力,其次因爲遠程覆蓋按鈕並不能保證按鈕不能被「點擊」(例如使用UI Automation框架)。