Browse Source

Merge pull request #1951 from worldbeater/master

feature: Support ReactiveUI WhenActivated
pull/1959/head
Steven Kirk 8 years ago
committed by GitHub
parent
commit
f338ba07b9
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      build.cake
  2. 2
      build/ReactiveUI.props
  3. 1
      samples/VirtualizationDemo/ViewModels/MainWindowViewModel.cs
  4. 4
      src/Avalonia.ReactiveUI/AppBuilderExtensions.cs
  5. 38
      src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs
  6. 14
      tests/Avalonia.ReactiveUI.UnitTests/Avalonia.ReactiveUI.UnitTests.csproj
  7. 89
      tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs

1
build.cake

@ -170,6 +170,7 @@ Task("Run-Unit-Tests-Impl")
RunCoreTest("./tests/Avalonia.Styling.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Visuals.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Skia.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.ReactiveUI.UnitTests", data.Parameters, false);
if (data.Parameters.IsRunningOnWindows)
{
RunCoreTest("./tests/Avalonia.Direct2D1.UnitTests", data.Parameters, false);

2
build/ReactiveUI.props

@ -1,5 +1,5 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="reactiveui" Version="8.7.1" />
<PackageReference Include="reactiveui" Version="9.0.1" />
</ItemGroup>
</Project>

1
samples/VirtualizationDemo/ViewModels/MainWindowViewModel.cs

@ -7,6 +7,7 @@ using System.Linq;
using Avalonia.Collections;
using Avalonia.Controls;
using Avalonia.Controls.Primitives;
using ReactiveUI.Legacy;
using ReactiveUI;
namespace VirtualizationDemo.ViewModels

4
src/Avalonia.ReactiveUI/AppBuilderExtensions.cs

@ -4,6 +4,7 @@
using Avalonia.Controls;
using Avalonia.Threading;
using ReactiveUI;
using Splat;
namespace Avalonia
{
@ -15,6 +16,9 @@ namespace Avalonia
return builder.AfterSetup(_ =>
{
RxApp.MainThreadScheduler = AvaloniaScheduler.Instance;
Locator.CurrentMutable.Register(
() => new AvaloniaActivationForViewFetcher(),
typeof(IActivationForViewFetcher));
});
}
}

38
src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs

@ -0,0 +1,38 @@
// 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.Reflection;
using System.Reactive.Linq;
using Avalonia;
using Avalonia.VisualTree;
using ReactiveUI;
namespace Avalonia
{
public class AvaloniaActivationForViewFetcher : IActivationForViewFetcher
{
public int GetAffinityForView(Type view)
{
return typeof(IVisual).GetTypeInfo().IsAssignableFrom(view.GetTypeInfo()) ? 10 : 0;
}
public IObservable<bool> GetActivationForView(IActivatable view)
{
if (!(view is IVisual visual)) return Observable.Return(false);
var viewLoaded = Observable
.FromEventPattern<VisualTreeAttachmentEventArgs>(
x => visual.AttachedToVisualTree += x,
x => visual.DetachedFromVisualTree -= x)
.Select(args => true);
var viewUnloaded = Observable
.FromEventPattern<VisualTreeAttachmentEventArgs>(
x => visual.DetachedFromVisualTree += x,
x => visual.DetachedFromVisualTree -= x)
.Select(args => false);
return viewLoaded
.Merge(viewUnloaded)
.DistinctUntilChanged();
}
}
}

14
tests/Avalonia.ReactiveUI.UnitTests/Avalonia.ReactiveUI.UnitTests.csproj

@ -0,0 +1,14 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<Import Project="..\..\build\UnitTests.NetCore.targets" />
<Import Project="..\..\build\Moq.props" />
<Import Project="..\..\build\XUnit.props" />
<Import Project="..\..\build\Rx.props" />
<Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
<ItemGroup>
<ProjectReference Include="..\Avalonia.UnitTests\Avalonia.UnitTests.csproj" />
<ProjectReference Include="..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj"/>
</ItemGroup>
</Project>

89
tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs

@ -0,0 +1,89 @@
using System;
using System.Reactive.Concurrency;
using System.Reactive.Disposables;
using Avalonia.Controls;
using Avalonia.Rendering;
using Avalonia.Platform;
using Avalonia.UnitTests;
using Avalonia;
using ReactiveUI;
using DynamicData;
using Xunit;
using Splat;
namespace Avalonia
{
public class AvaloniaActivationForViewFetcherTest
{
public class TestUserControl : UserControl, IActivatable { }
public class TestUserControlWithWhenActivated : UserControl, IActivatable
{
public bool Active { get; private set; }
public TestUserControlWithWhenActivated()
{
this.WhenActivated(disposables => {
Active = true;
Disposable
.Create(() => Active = false)
.DisposeWith(disposables);
});
}
}
[Fact]
public void Visual_Element_Is_Activated_And_Deactivated()
{
var userControl = new TestUserControl();
var activationForViewFetcher = new AvaloniaActivationForViewFetcher();
activationForViewFetcher
.GetActivationForView(userControl)
.ToObservableChangeSet(scheduler: ImmediateScheduler.Instance)
.Bind(out var activated)
.Subscribe();
var fakeRenderedDecorator = new TestRoot();
fakeRenderedDecorator.Child = userControl;
Assert.True(activated[0]);
Assert.Equal(1, activated.Count);
fakeRenderedDecorator.Child = null;
Assert.True(activated[0]);
Assert.False(activated[1]);
Assert.Equal(2, activated.Count);
}
[Fact]
public void Get_Affinity_For_View_Should_Return_Non_Zero_For_Visual_Elements()
{
var userControl = new TestUserControl();
var activationForViewFetcher = new AvaloniaActivationForViewFetcher();
var forUserControl = activationForViewFetcher.GetAffinityForView(userControl.GetType());
var forNonUserControl = activationForViewFetcher.GetAffinityForView(typeof(object));
Assert.NotEqual(0, forUserControl);
Assert.Equal(0, forNonUserControl);
}
[Fact]
public void Activation_For_View_Fetcher_Should_Support_When_Activated()
{
Locator.CurrentMutable.RegisterConstant(
new AvaloniaActivationForViewFetcher(),
typeof(IActivationForViewFetcher));
var userControl = new TestUserControlWithWhenActivated();
Assert.False(userControl.Active);
var fakeRenderedDecorator = new TestRoot();
fakeRenderedDecorator.Child = userControl;
Assert.True(userControl.Active);
fakeRenderedDecorator.Child = null;
Assert.False(userControl.Active);
}
}
}
Loading…
Cancel
Save