Browse Source

Added GetObservable for routed events.

Fixes #905.
pull/906/head
Steven Kirk 9 years ago
parent
commit
4ca0bb72b2
  1. 30
      src/Avalonia.Interactivity/InteractiveExtensions.cs
  2. 21
      tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj
  3. 18
      tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs
  4. 6
      tests/Avalonia.Interactivity.UnitTests/packages.config

30
src/Avalonia.Interactivity/InteractiveExtensions.cs

@ -1,8 +1,10 @@
// Copyright (c) The Avalonia Project. All rights reserved. // 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. // 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.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive.Linq;
namespace Avalonia.Interactivity namespace Avalonia.Interactivity
{ {
@ -11,12 +13,36 @@ namespace Avalonia.Interactivity
/// </summary> /// </summary>
public static class InteractiveExtensions public static class InteractiveExtensions
{ {
/// <summary>
/// Gets an observable for a <see cref="RoutedEvent{TEventArgs}"/>.
/// </summary>
/// <param name="o">The object to listen for events on.</param>
/// <param name="routedEvent">The routed event.</param>
/// <param name="routes">The routing strategies to listen to.</param>
/// <param name="handledEventsToo">Whether handled events should also be listened for.</param>
/// <returns>
/// An observable which fires each time the event is raised.
/// </returns>
public static IObservable<TEventArgs> GetObservable<TEventArgs>(
this IInteractive o,
RoutedEvent<TEventArgs> routedEvent,
RoutingStrategies routes = RoutingStrategies.Direct | RoutingStrategies.Bubble,
bool handledEventsToo = false)
where TEventArgs : RoutedEventArgs
{
return Observable.Create<TEventArgs>(x => o.AddHandler(
routedEvent,
(_, e) => x.OnNext(e),
routes,
handledEventsToo));
}
/// <summary> /// <summary>
/// Gets the route for bubbling events from the specified interactive. /// Gets the route for bubbling events from the specified interactive.
/// </summary> /// </summary>
/// <param name="interactive">The interactive.</param> /// <param name="interactive">The interactive.</param>
/// <returns>The event route.</returns> /// <returns>The event route.</returns>
public static IEnumerable<IInteractive> GetBubbleEventRoute(this IInteractive interactive) internal static IEnumerable<IInteractive> GetBubbleEventRoute(this IInteractive interactive)
{ {
while (interactive != null) while (interactive != null)
{ {
@ -30,7 +56,7 @@ namespace Avalonia.Interactivity
/// </summary> /// </summary>
/// <param name="interactive">The interactive.</param> /// <param name="interactive">The interactive.</param>
/// <returns>The event route.</returns> /// <returns>The event route.</returns>
public static IEnumerable<IInteractive> GetTunnelEventRoute(this IInteractive interactive) internal static IEnumerable<IInteractive> GetTunnelEventRoute(this IInteractive interactive)
{ {
return interactive.GetBubbleEventRoute().Reverse(); return interactive.GetBubbleEventRoute().Reverse();
} }

21
tests/Avalonia.Interactivity.UnitTests/Avalonia.Interactivity.UnitTests.csproj

@ -37,11 +37,32 @@
<ItemGroup> <ItemGroup>
<Reference Include="System" /> <Reference Include="System" />
<Reference Include="System.Core" /> <Reference Include="System.Core" />
<Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Reactive.Core.3.0.0\lib\net45\System.Reactive.Core.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Reactive.Interfaces.3.0.0\lib\net45\System.Reactive.Interfaces.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Reactive.Linq, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Reactive.Linq.3.0.0\lib\net45\System.Reactive.Linq.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Reactive.PlatformServices, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Reactive.Windows.Threading, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Reactive.Windows.Threading.3.0.0\lib\net45\System.Reactive.Windows.Threading.dll</HintPath>
<Private>True</Private>
</Reference>
<Reference Include="System.Xml.Linq" /> <Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" /> <Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" /> <Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" /> <Reference Include="System.Data" />
<Reference Include="System.Xml" /> <Reference Include="System.Xml" />
<Reference Include="WindowsBase" />
<Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c"> <Reference Include="xunit.abstractions, Version=2.0.0.0, Culture=neutral, PublicKeyToken=8d05b1bb7a6fdb6c">
<HintPath>..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll</HintPath> <HintPath>..\..\packages\xunit.abstractions.2.0.0\lib\net35\xunit.abstractions.dll</HintPath>
</Reference> </Reference>

18
tests/Avalonia.Interactivity.UnitTests/InteractiveTests.cs

@ -340,6 +340,24 @@ namespace Avalonia.Interactivity.UnitTests
Assert.True(target.GetVisualParent<TestInteractive>().ClassHandlerInvoked); Assert.True(target.GetVisualParent<TestInteractive>().ClassHandlerInvoked);
} }
[Fact]
public void GetObservable_Should_Listen_To_Event()
{
var ev = new RoutedEvent<RoutedEventArgs>("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( private TestInteractive CreateTree(
RoutedEvent ev, RoutedEvent ev,
EventHandler<RoutedEventArgs> handler, EventHandler<RoutedEventArgs> handler,

6
tests/Avalonia.Interactivity.UnitTests/packages.config

@ -1,5 +1,11 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<packages> <packages>
<package id="System.Reactive" version="3.0.0" targetFramework="net45" />
<package id="System.Reactive.Core" version="3.0.0" targetFramework="net45" />
<package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="net45" />
<package id="System.Reactive.Linq" version="3.0.0" targetFramework="net45" />
<package id="System.Reactive.PlatformServices" version="3.0.0" targetFramework="net45" />
<package id="System.Reactive.Windows.Threading" version="3.0.0" targetFramework="net45" />
<package id="xunit" version="2.1.0" targetFramework="net45" /> <package id="xunit" version="2.1.0" targetFramework="net45" />
<package id="xunit.abstractions" version="2.0.0" targetFramework="net45" /> <package id="xunit.abstractions" version="2.0.0" targetFramework="net45" />
<package id="xunit.assert" version="2.1.0" targetFramework="net45" /> <package id="xunit.assert" version="2.1.0" targetFramework="net45" />

Loading…
Cancel
Save