2011-10-12 49 views
1

我想在我的Silverlight UI中實現延遲的MouseEnter事件處理程序。使用DispatcherTimer等這種'經典'方法,我現在正在嘗試使用Reactive擴展來做同樣的事情。這被認爲是更簡潔易讀,但不知何故,我無法實現的目標,這就是:如何使用Silverlight和Reactive擴展實現延遲的MouseEnter事件?

  • 當鼠標進入一些UI控件,一個方法需要被調用,
  • 但應該在經過一段時間後才能完成,即1000毫秒,在這段時間內鼠標保持在控制範圍內,因此如果鼠標在該時間段之前離開控件,則根本沒有任何事情發生,事件應該被取消'

我經歷了RX文檔,這是相當抽象的而這種實際的例子是不存在的。根據網上找到一些例子,我想出了這樣的事情:

Observable.Throttle(
     Observable.FromEventPattern(LanguageSelector, "MouseEnter"), TimeSpan.FromSeconds(2)) 
     .TakeUntil(Observable.FromEventPattern(LanguageSelector, "MouseLeave")) 
     .ObserveOnDispatcher() 
     .Subscribe(e => 
     { 
      ShowPopup(); 
     }); 

這似乎很好地工作,但只有一次。一旦鼠標離開控制,它將不再工作,我的彈出不會再被觸發。有關如何做到這一點的更好的想法?

在此先感謝!

回答

1

您的解決方案只會觸發一次的原因是TakeUntil。一旦MouseLeave發生,您的可觀測值就會被處置。 SelectMany方法可以用來克服這一點:

var mouseEnter = Observable.FromEventPattern(LanguageSelector, "MouseEnter"); 
var mouseLeave = Observable.FromEventPattern(LanguageSelector, "MouseLeave"); 

mouseEnter 
    .SelectMany(mousePos => 
     Observable.Timer(TimeSpan.FromSeconds(2)).ObserveOnDispatcher() 
     .TakeUntil(mouseLeave)) 
    .Subscribe(e => ShowPopup()); 
+0

謝謝,馬特,這工作只是完美!學習如何思考「RX方式」需要時間,但看起來它絕對值得! – Tomasz

+0

@Tomasz由於Matt的解決方案有效,請考慮通過單擊複選標記來接受他的答案。這鼓勵人們在未來回答你的問題。 –