은 다음
public static IDisposable GetClick(this UIElement item, Action clickAction)
{
var obs1 = Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(
h => (s, e) => h(s, e),
h => item.MouseLeftButtonDown += h,
h => item.MouseLeftButtonDown -= h);
var obs2 = Observable.FromEventPattern<MouseButtonEventHandler, MouseButtonEventArgs>(
h => (s, e) => h(s, e),
h => item.MouseLeftButtonUp += h,
h => item.MouseLeftButtonUp -= h);
var obs3 = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(
h => (s, e) => h(s, e),
h => item.MouseLeave += h,
h => item.MouseLeave -= h);
var obs4 = Observable.FromEventPattern<MouseEventHandler, MouseEventArgs>(
h => (s, e) => h(s, e),
h => item.MouseEnter += h,
h => item.MouseEnter -= h);
var finalObs = ???
return finalObs.Subscribe(x => clickAction.Invoke());
}가 작동하는 것 같다,하지만 난 그게 깔끔한 방법으로 그것을 할 수 있다고 생각 .
var click = mouseEnter
.SelectMany(_ => mouseDown.TakeUntil(mouseLeave))
.SelectMany(_ => mouseUp.TakeUntil(mouseLeave).Take(1));
나는 ... obs1
obs2
mouseUp
에, mouseDown
에, click
에 finalObs
이름을 변경 한
편집 : 추가 테이크 (1) 결함이 Enigmativity
EDIT (지적 해결하기 위해 2) :
다음은 내가 더 좋아하는 또 다른 해결책입니다.
당신은 모르기 때문에 mouseUp, mouseDown에 .Select(_ => "D")
의 정의에 .Select(_ => "U")
를 추가해야합니다 ...
var click = Observable.Merge(mouseDown, mouseUp, mouseLeave, mouseEnter)
.Scan((s, c) => c == "L" ? "" : s + c) // Create a string of the events, reset on mouseLeave
.Where(s => s.Length >= 2 && s.Substring(s.Length - 2) == "DU");
그것에 대해 생각하면,이 경우에 정확히 올바른 동작을 취득 불가능 경우 사용자 마우스 항목 위로 이동 한 다음 항목 밖으로 이동 한 다음 뒤로 이동하고 마우스를 위로 이동합니다. 이것은 항목을 넘지 않을 때는 마우스 업을하지 않기 때문에 마우스를 올리지 않았다고 확신 할 수 없으므로 밖에있는 동안 마우스를 아래로 두었 기 때문입니다.
체크 아웃 : http://rxwiki.wikidot.com/101samples#toc50 나는'CombineLatest' 아주 잘 난 당신의 코드를 테스트하고 가까운 – Pellared