diff --git a/src/Avalonia.Interactivity/InteractiveExtensions.cs b/src/Avalonia.Interactivity/InteractiveExtensions.cs index 2507fc6866..b03590951b 100644 --- a/src/Avalonia.Interactivity/InteractiveExtensions.cs +++ b/src/Avalonia.Interactivity/InteractiveExtensions.cs @@ -1,8 +1,10 @@ // Copyright (c) The Avalonia Project. All rights reserved. // Licensed under the MIT license. See licence.md file in the project root for full license information. +using System; using System.Collections.Generic; using System.Linq; +using System.Reactive.Linq; namespace Avalonia.Interactivity { @@ -11,12 +13,36 @@ namespace Avalonia.Interactivity /// public static class InteractiveExtensions { + /// + /// Gets an observable for a . + /// + /// The object to listen for events on. + /// The routed event. + /// The routing strategies to listen to. + /// Whether handled events should also be listened for. + /// + /// An observable which fires each time the event is raised. + /// + public static IObservable GetObservable( + this IInteractive o, + RoutedEvent routedEvent, + RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble, + bool handledEventsToo = false) + where TEventArgs : RoutedEventArgs + { + return Observable.Create(x => o.AddHandler( + routedEvent, + (_, e) => x.OnNext(e), + routes, + handledEventsToo)); + } + /// /// Gets the route for bubbling events from the specified interactive. /// /// The interactive. /// The event route. - public static IEnumerable GetBubbleEventRoute(this IInteractive interactive) + internal static IEnumerable GetBubbleEventRoute(this IInteractive interactive) { while (interactive != null) { @@ -30,7 +56,7 @@ namespace Avalonia.Interactivity /// /// The interactive. /// The event route. - public static IEnumerable GetTunnelEventRoute(this IInteractive interactive) + internal static IEnumerable GetTunnelEventRoute(this IInteractive interactive) { return interactive.GetBubbleEventRoute().Reverse(); } diff --git a/tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj b/tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj index 6dfefe1a63..d8a6ee2506 100644 --- a/tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj +++ b/tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj @@ -37,11 +37,32 @@ + + ..\..\packages\System.Reactive.Core.3.0.0\lib\net45\System.Reactive.Core.dll + True + + + ..\..\packages\System.Reactive.Interfaces.3.0.0\lib\net45\System.Reactive.Interfaces.dll + True + + + ..\..\packages\System.Reactive.Linq.3.0.0\lib\net45\System.Reactive.Linq.dll + True + + + ..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\net45\System.Reactive.PlatformServices.dll + True + + + ..\..\packages\System.Reactive.Windows.Threading.3.0.0\lib\net45\System.Reactive.Windows.Threading.dll + True + + ..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll diff --git a/tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs b/tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs index f107490ced..dd0974fad0 100644 --- a/tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs +++ b/tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs @@ -340,6 +340,24 @@ namespace Avalonia.Interactivity.UnitTests Assert.True(target.GetVisualParent().ClassHandlerInvoked); } + [Fact] + public void GetObservable_Should_Listen_To_Event() + { + var ev = new RoutedEvent("test", RoutingStrategies.Direct, typeof(TestInteractive)); + var target = new TestInteractive(); + var called = 0; + var subscription = target.GetObservable(ev).Subscribe(_ => ++called); + + var args = new RoutedEventArgs(ev, target); + target.RaiseEvent(args); + + subscription.Dispose(); + + target.RaiseEvent(args); + + Assert.Equal(1, called); + } + private TestInteractive CreateTree( RoutedEvent ev, EventHandler handler, diff --git a/tests/Avalonia.Interactivity.UnitTests/packages.config b/tests/Avalonia.Interactivity.UnitTests/packages.config index dcbf45edf0..953a4a666d 100644 --- a/tests/Avalonia.Interactivity.UnitTests/packages.config +++ b/tests/Avalonia.Interactivity.UnitTests/packages.config @@ -1,5 +1,11 @@  + + + + + +