Browse Source

Merge pull request #2266 from AvaloniaUI/feature/window-open

Added TopLevel.Opened event and use it for RxUI Activation.
pull/2269/head
Steven Kirk 7 years ago
committed by GitHub
parent
commit
251f825513
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 31
      Avalonia.sln
  2. 11
      src/Avalonia.Controls/TopLevel.cs
  3. 2
      src/Avalonia.Controls/Window.cs
  4. 3
      src/Avalonia.Controls/WindowBase.cs
  5. 6
      src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs
  6. 16
      tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs
  7. 21
      tests/Avalonia.Controls.UnitTests/WindowTests.cs
  8. 35
      tests/Avalonia.ReactiveUI.UnitTests/AvaloniaActivationForViewFetcherTest.cs

31
Avalonia.sln

@ -196,9 +196,11 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "_build", "nukebuild\_build.
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Animation.UnitTests", "tests\Avalonia.Animation.UnitTests\Avalonia.Animation.UnitTests.csproj", "{AF227847-E65C-4BE9-BCE9-B551357788E0}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.X11", "src\Avalonia.X11\Avalonia.X11.csproj", "{41B02319-965D-4945-8005-C1A3D1224165}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.X11", "src\Avalonia.X11\Avalonia.X11.csproj", "{41B02319-965D-4945-8005-C1A3D1224165}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PlatformSanityChecks", "samples\PlatformSanityChecks\PlatformSanityChecks.csproj", "{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "PlatformSanityChecks", "samples\PlatformSanityChecks\PlatformSanityChecks.csproj", "{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI.UnitTests", "tests\Avalonia.ReactiveUI.UnitTests\Avalonia.ReactiveUI.UnitTests.csproj", "{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
@ -1819,6 +1821,30 @@ Global
{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}.Release|iPhone.Build.0 = Release|Any CPU
{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.AppStore|Any CPU.Build.0 = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.AppStore|iPhone.Build.0 = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|Any CPU.Build.0 = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|iPhone.Build.0 = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|Any CPU.ActiveCfg = Release|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|Any CPU.Build.0 = Release|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|iPhone.ActiveCfg = Release|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|iPhone.Build.0 = Release|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@ -1875,6 +1901,7 @@ Global
{AF227847-E65C-4BE9-BCE9-B551357788E0} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
{41B02319-965D-4945-8005-C1A3D1224165} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
{D775DECB-4E00-4ED5-A75A-5FCE58ADFF0B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
{AF915D5C-AB00-4EA0-B5E6-001F4AE84E68} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {87366D66-1391-4D90-8999-95A620AD786A}

11
src/Avalonia.Controls/TopLevel.cs

@ -136,6 +136,11 @@ namespace Avalonia.Controls
}
}
/// <summary>
/// Fired when the window is opened.
/// </summary>
public event EventHandler Opened;
/// <summary>
/// Fired when the window is closed.
/// </summary>
@ -311,6 +316,12 @@ namespace Avalonia.Controls
$"Control '{GetType().Name}' is a top level control and cannot be added as a child.");
}
/// <summary>
/// Raises the <see cref="Opened"/> event.
/// </summary>
/// <param name="e">The event args.</param>
protected virtual void OnOpened(EventArgs e) => Opened?.Invoke(this, e);
/// <summary>
/// Tries to get a service from an <see cref="IAvaloniaDependencyResolver"/>, logging a
/// warning if not found.

2
src/Avalonia.Controls/Window.cs

@ -389,6 +389,7 @@ namespace Avalonia.Controls
Renderer?.Start();
}
SetWindowStartupLocation(Owner?.PlatformImpl);
OnOpened(EventArgs.Empty);
}
/// <summary>
@ -458,6 +459,7 @@ namespace Avalonia.Controls
owner.Activate();
result.SetResult((TResult)(_dialogResult ?? default(TResult)));
});
OnOpened(EventArgs.Empty);
}
SetWindowStartupLocation(owner);

3
src/Avalonia.Controls/WindowBase.cs

@ -163,7 +163,7 @@ namespace Avalonia.Controls
}
/// <summary>
/// Shows the popup.
/// Shows the window.
/// </summary>
public virtual void Show()
{
@ -181,6 +181,7 @@ namespace Avalonia.Controls
}
PlatformImpl?.Show();
Renderer?.Start();
OnOpened(EventArgs.Empty);
}
finally
{

6
src/Avalonia.ReactiveUI/AvaloniaActivationForViewFetcher.cs

@ -29,8 +29,8 @@ namespace Avalonia
{
var windowLoaded = Observable
.FromEventPattern(
x => window.Initialized += x,
x => window.Initialized -= x)
x => window.Opened += x,
x => window.Opened -= x)
.Select(args => true);
var windowUnloaded = Observable
.FromEventPattern(
@ -59,4 +59,4 @@ namespace Avalonia
.DistinctUntilChanged();
}
}
}
}

16
tests/Avalonia.Controls.UnitTests/WindowBaseTests.cs

@ -199,6 +199,22 @@ namespace Avalonia.Controls.UnitTests
}
}
[Fact]
public void Showing_Should_Raise_Opened()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var target = new TestWindowBase();
var raised = false;
target.Opened += (s, e) => raised = true;
target.Show();
Assert.True(raised);
}
}
[Fact]
public void Hiding_Should_Stop_Renderer()
{

21
tests/Avalonia.Controls.UnitTests/WindowTests.cs

@ -228,18 +228,35 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void ShowDialog_Should_Start_Renderer()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var parent = Mock.Of<IWindowImpl>();
var renderer = new Mock<IRenderer>();
var target = new Window(CreateImpl(renderer));
target.Show();
target.ShowDialog<object>(parent);
renderer.Verify(x => x.Start(), Times.Once);
}
}
[Fact]
public void ShowDialog_Should_Raise_Opened()
{
using (UnitTestApplication.Start(TestServices.StyledWindow))
{
var parent = Mock.Of<IWindowImpl>();
var target = new Window();
var raised = false;
target.Opened += (s, e) => raised = true;
target.ShowDialog<object>(parent);
Assert.True(raised);
}
}
[Fact]
public void Hiding_Should_Stop_Renderer()
{

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

@ -10,6 +10,7 @@ using ReactiveUI;
using DynamicData;
using Xunit;
using Splat;
using Avalonia.Markup.Xaml;
namespace Avalonia
{
@ -70,12 +71,40 @@ namespace Avalonia
public class ActivatableWindow : ReactiveWindow<ActivatableViewModel>
{
public ActivatableWindow() => this.WhenActivated(disposables => { });
public ActivatableWindow()
{
InitializeComponent();
Assert.IsType<Border>(Content);
this.WhenActivated(disposables => { });
}
private void InitializeComponent()
{
var loader = new AvaloniaXamlLoader();
loader.Load(@"
<Window xmlns='https://github.com/avaloniaui'>
<Border/>
</Window>", null, this);
}
}
public class ActivatableUserControl : ReactiveUserControl<ActivatableViewModel>
{
public ActivatableUserControl() => this.WhenActivated(disposables => { });
public ActivatableUserControl()
{
InitializeComponent();
Assert.IsType<Border>(Content);
this.WhenActivated(disposables => { });
}
private void InitializeComponent()
{
var loader = new AvaloniaXamlLoader();
loader.Load(@"
<UserControl xmlns='https://github.com/avaloniaui'>
<Border/>
</UserControl>", null, this);
}
}
public AvaloniaActivationForViewFetcherTest()
@ -183,4 +212,4 @@ namespace Avalonia
Assert.False(viewModel.IsActivated);
}
}
}
}

Loading…
Cancel
Save