Browse Source

Merge branch 'master' into pointer-capture-transfer-fix

pull/3161/head
Steven Kirk 7 years ago
committed by GitHub
parent
commit
da1ff18a5d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 5
      src/Avalonia.Controls/AppBuilderBase.cs
  2. 9
      src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs
  3. 13
      src/Avalonia.Controls/ColumnDefinition.cs
  4. 54
      src/Avalonia.Controls/DefinitionBase.cs
  5. 1
      src/Avalonia.Controls/DesktopApplicationExtensions.cs
  6. 12
      src/Avalonia.Controls/Grid.cs
  7. 2
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  8. 13
      src/Avalonia.Controls/RowDefinition.cs
  9. 18
      tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs
  10. 286
      tests/Avalonia.Controls.UnitTests/GridTests.cs
  11. 6
      tests/Avalonia.ReactiveUI.UnitTests/AutoSuspendHelperTest.cs

5
src/Avalonia.Controls/AppBuilderBase.cs

@ -125,9 +125,8 @@ namespace Avalonia.Controls
}); });
// Copy-pasted because we can't call extension methods due to generic constraints // Copy-pasted because we can't call extension methods due to generic constraints
var lifetime = new ClassicDesktopStyleApplicationLifetime(Instance) {ShutdownMode = ShutdownMode.OnMainWindowClose}; var lifetime = new ClassicDesktopStyleApplicationLifetime() {ShutdownMode = ShutdownMode.OnMainWindowClose};
Instance.ApplicationLifetime = lifetime; SetupWithLifetime(lifetime);
SetupWithoutStarting();
lifetime.Start(Array.Empty<string>()); lifetime.Start(Array.Empty<string>());
} }

9
src/Avalonia.Controls/ApplicationLifetimes/ClassicDesktopStyleApplicationLifetime.cs

@ -5,12 +5,12 @@ using System.Threading;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.ApplicationLifetimes; using Avalonia.Controls.ApplicationLifetimes;
using Avalonia.Interactivity; using Avalonia.Interactivity;
using Avalonia.Threading;
namespace Avalonia.Controls.ApplicationLifetimes namespace Avalonia.Controls.ApplicationLifetimes
{ {
public class ClassicDesktopStyleApplicationLifetime : IClassicDesktopStyleApplicationLifetime, IDisposable public class ClassicDesktopStyleApplicationLifetime : IClassicDesktopStyleApplicationLifetime, IDisposable
{ {
private readonly Application _app;
private int _exitCode; private int _exitCode;
private CancellationTokenSource _cts; private CancellationTokenSource _cts;
private bool _isShuttingDown; private bool _isShuttingDown;
@ -34,12 +34,11 @@ namespace Avalonia.Controls.ApplicationLifetimes
_activeLifetime?._windows.Add((Window)sender); _activeLifetime?._windows.Add((Window)sender);
} }
public ClassicDesktopStyleApplicationLifetime(Application app) public ClassicDesktopStyleApplicationLifetime()
{ {
if (_activeLifetime != null) if (_activeLifetime != null)
throw new InvalidOperationException( throw new InvalidOperationException(
"Can not have multiple active ClassicDesktopStyleApplicationLifetime instances and the previously created one was not disposed"); "Can not have multiple active ClassicDesktopStyleApplicationLifetime instances and the previously created one was not disposed");
_app = app;
_activeLifetime = this; _activeLifetime = this;
} }
@ -103,7 +102,7 @@ namespace Avalonia.Controls.ApplicationLifetimes
Startup?.Invoke(this, new ControlledApplicationLifetimeStartupEventArgs(args)); Startup?.Invoke(this, new ControlledApplicationLifetimeStartupEventArgs(args));
_cts = new CancellationTokenSource(); _cts = new CancellationTokenSource();
MainWindow?.Show(); MainWindow?.Show();
_app.Run(_cts.Token); Dispatcher.UIThread.MainLoop(_cts.Token);
Environment.ExitCode = _exitCode; Environment.ExitCode = _exitCode;
return _exitCode; return _exitCode;
} }
@ -124,7 +123,7 @@ namespace Avalonia
this T builder, string[] args, ShutdownMode shutdownMode = ShutdownMode.OnLastWindowClose) this T builder, string[] args, ShutdownMode shutdownMode = ShutdownMode.OnLastWindowClose)
where T : AppBuilderBase<T>, new() where T : AppBuilderBase<T>, new()
{ {
var lifetime = new ClassicDesktopStyleApplicationLifetime(builder.Instance) {ShutdownMode = shutdownMode}; var lifetime = new ClassicDesktopStyleApplicationLifetime() {ShutdownMode = shutdownMode};
builder.SetupWithLifetime(lifetime); builder.SetupWithLifetime(lifetime);
return lifetime.Start(args); return lifetime.Start(args);
} }

13
src/Avalonia.Controls/ColumnDefinition.cs

@ -26,6 +26,16 @@ namespace Avalonia.Controls
public static readonly StyledProperty<GridLength> WidthProperty = public static readonly StyledProperty<GridLength> WidthProperty =
AvaloniaProperty.Register<ColumnDefinition, GridLength>(nameof(Width), new GridLength(1, GridUnitType.Star)); AvaloniaProperty.Register<ColumnDefinition, GridLength>(nameof(Width), new GridLength(1, GridUnitType.Star));
/// <summary>
/// Initializes static members of the <see cref="ColumnDefinition"/> class.
/// </summary>
static ColumnDefinition()
{
AffectsParentMeasure(MinWidthProperty, MaxWidthProperty);
WidthProperty.Changed.AddClassHandler<DefinitionBase>(OnUserSizePropertyChanged);
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="ColumnDefinition"/> class. /// Initializes a new instance of the <see cref="ColumnDefinition"/> class.
/// </summary> /// </summary>
@ -68,7 +78,6 @@ namespace Avalonia.Controls
} }
set set
{ {
Parent?.InvalidateMeasure();
SetValue(MaxWidthProperty, value); SetValue(MaxWidthProperty, value);
} }
} }
@ -84,7 +93,6 @@ namespace Avalonia.Controls
} }
set set
{ {
Parent?.InvalidateMeasure();
SetValue(MinWidthProperty, value); SetValue(MinWidthProperty, value);
} }
} }
@ -100,7 +108,6 @@ namespace Avalonia.Controls
} }
set set
{ {
Parent?.InvalidateMeasure();
SetValue(WidthProperty, value); SetValue(WidthProperty, value);
} }
} }

54
src/Avalonia.Controls/DefinitionBase.cs

@ -7,9 +7,6 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Avalonia;
using Avalonia.Collections;
using Avalonia.Utilities; using Avalonia.Utilities;
namespace Avalonia.Controls namespace Avalonia.Controls
@ -50,6 +47,8 @@ namespace Avalonia.Controls
} }
} }
} }
Parent?.InvalidateMeasure();
} }
/// <summary> /// <summary>
@ -63,6 +62,8 @@ namespace Avalonia.Controls
_sharedState.RemoveMember(this); _sharedState.RemoveMember(this);
_sharedState = null; _sharedState = null;
} }
Parent?.InvalidateMeasure();
} }
/// <summary> /// <summary>
@ -114,6 +115,36 @@ namespace Avalonia.Controls
} }
} }
/// <remarks>
/// Notifies parent <see cref="Grid"/> or size scope that definition size has been changed.
/// </remarks>
internal static void OnUserSizePropertyChanged(DefinitionBase definition, AvaloniaPropertyChangedEventArgs e)
{
if (definition.Parent == null)
{
return;
}
if (definition._sharedState != null)
{
definition._sharedState.Invalidate();
}
else
{
GridUnitType oldUnitType = ((GridLength)e.OldValue).GridUnitType;
GridUnitType newUnitType = ((GridLength)e.NewValue).GridUnitType;
if (oldUnitType != newUnitType)
{
definition.Parent.Invalidate();
}
else
{
definition.Parent.InvalidateMeasure();
}
}
}
/// <summary> /// <summary>
/// Returns <c>true</c> if this definition is a part of shared group. /// Returns <c>true</c> if this definition is a part of shared group.
/// </summary> /// </summary>
@ -730,5 +761,22 @@ namespace Avalonia.Controls
SharedSizeGroupProperty.Changed.AddClassHandler<DefinitionBase>(OnSharedSizeGroupPropertyChanged); SharedSizeGroupProperty.Changed.AddClassHandler<DefinitionBase>(OnSharedSizeGroupPropertyChanged);
PrivateSharedSizeScopeProperty.Changed.AddClassHandler<DefinitionBase>(OnPrivateSharedSizeScopePropertyChanged); PrivateSharedSizeScopeProperty.Changed.AddClassHandler<DefinitionBase>(OnPrivateSharedSizeScopePropertyChanged);
} }
/// <summary>
/// Marks a property on a definition as affecting the parent grid's measurement.
/// </summary>
/// <param name="properties">The properties.</param>
protected static void AffectsParentMeasure(params AvaloniaProperty[] properties)
{
void Invalidate(AvaloniaPropertyChangedEventArgs e)
{
(e.Sender as DefinitionBase)?.Parent?.InvalidateMeasure();
}
foreach (var property in properties)
{
property.Changed.Subscribe(Invalidate);
}
}
} }
} }

1
src/Avalonia.Controls/DesktopApplicationExtensions.cs

@ -50,6 +50,7 @@ namespace Avalonia.Controls
/// On desktop-style platforms runs the application's main loop with custom CancellationToken /// On desktop-style platforms runs the application's main loop with custom CancellationToken
/// without setting a lifetime. /// without setting a lifetime.
/// </summary> /// </summary>
/// <param name="app">The application.</param>
/// <param name="token">The token to track.</param> /// <param name="token">The token to track.</param>
public static void Run(this Application app, CancellationToken token) public static void Run(this Application app, CancellationToken token)
{ {

12
src/Avalonia.Controls/Grid.cs

@ -6,6 +6,7 @@
using System; using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Collections.Specialized;
using System.Diagnostics; using System.Diagnostics;
using System.Linq; using System.Linq;
using System.Threading; using System.Threading;
@ -178,6 +179,7 @@ namespace Avalonia.Controls
if (_data == null) { _data = new ExtendedData(); } if (_data == null) { _data = new ExtendedData(); }
_data.ColumnDefinitions = value; _data.ColumnDefinitions = value;
_data.ColumnDefinitions.Parent = this; _data.ColumnDefinitions.Parent = this;
InvalidateMeasure();
} }
} }
@ -198,6 +200,7 @@ namespace Avalonia.Controls
if (_data == null) { _data = new ExtendedData(); } if (_data == null) { _data = new ExtendedData(); }
_data.RowDefinitions = value; _data.RowDefinitions = value;
_data.RowDefinitions.Parent = this; _data.RowDefinitions.Parent = this;
InvalidateMeasure();
} }
} }
@ -569,6 +572,15 @@ namespace Avalonia.Controls
return (arrangeSize); return (arrangeSize);
} }
/// <summary>
/// <see cref="Panel.ChildrenChanged"/>
/// </summary>
protected override void ChildrenChanged(object sender, NotifyCollectionChangedEventArgs e)
{
CellsStructureDirty = true;
base.ChildrenChanged(sender, e);
}
/// <summary> /// <summary>
/// Invalidates grid caches and makes the grid dirty for measure. /// Invalidates grid caches and makes the grid dirty for measure.
/// </summary> /// </summary>

2
src/Avalonia.Controls/Primitives/PopupRoot.cs

@ -41,6 +41,8 @@ namespace Avalonia.Controls.Primitives
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="PopupRoot"/> class. /// Initializes a new instance of the <see cref="PopupRoot"/> class.
/// </summary> /// </summary>
/// <param name="parent">The popup parent.</param>
/// <param name="impl">The popup implementation.</param>
/// <param name="dependencyResolver"> /// <param name="dependencyResolver">
/// The dependency resolver to use. If null the default dependency resolver will be used. /// The dependency resolver to use. If null the default dependency resolver will be used.
/// </param> /// </param>

13
src/Avalonia.Controls/RowDefinition.cs

@ -26,6 +26,16 @@ namespace Avalonia.Controls
public static readonly StyledProperty<GridLength> HeightProperty = public static readonly StyledProperty<GridLength> HeightProperty =
AvaloniaProperty.Register<RowDefinition, GridLength>(nameof(Height), new GridLength(1, GridUnitType.Star)); AvaloniaProperty.Register<RowDefinition, GridLength>(nameof(Height), new GridLength(1, GridUnitType.Star));
/// <summary>
/// Initializes static members of the <see cref="RowDefinition"/> class.
/// </summary>
static RowDefinition()
{
AffectsParentMeasure(MaxHeightProperty, MinHeightProperty);
HeightProperty.Changed.AddClassHandler<DefinitionBase>(OnUserSizePropertyChanged);
}
/// <summary> /// <summary>
/// Initializes a new instance of the <see cref="RowDefinition"/> class. /// Initializes a new instance of the <see cref="RowDefinition"/> class.
/// </summary> /// </summary>
@ -68,7 +78,6 @@ namespace Avalonia.Controls
} }
set set
{ {
Parent?.InvalidateMeasure();
SetValue(MaxHeightProperty, value); SetValue(MaxHeightProperty, value);
} }
} }
@ -84,7 +93,6 @@ namespace Avalonia.Controls
} }
set set
{ {
Parent?.InvalidateMeasure();
SetValue(MinHeightProperty, value); SetValue(MinHeightProperty, value);
} }
} }
@ -100,7 +108,6 @@ namespace Avalonia.Controls
} }
set set
{ {
Parent?.InvalidateMeasure();
SetValue(HeightProperty, value); SetValue(HeightProperty, value);
} }
} }

18
tests/Avalonia.Controls.UnitTests/DesktopStyleApplicationLifetimeTests.cs

@ -16,7 +16,7 @@ namespace Avalonia.Controls.UnitTests
public void Should_Set_ExitCode_After_Shutdown() public void Should_Set_ExitCode_After_Shutdown()
{ {
using (UnitTestApplication.Start(TestServices.MockThreadingInterface)) using (UnitTestApplication.Start(TestServices.MockThreadingInterface))
using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
lifetime.Shutdown(1337); lifetime.Shutdown(1337);
@ -31,7 +31,7 @@ namespace Avalonia.Controls.UnitTests
public void Should_Close_All_Remaining_Open_Windows_After_Explicit_Exit_Call() public void Should_Close_All_Remaining_Open_Windows_After_Explicit_Exit_Call()
{ {
using (UnitTestApplication.Start(TestServices.StyledWindow)) using (UnitTestApplication.Start(TestServices.StyledWindow))
using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
var windows = new List<Window> { new Window(), new Window(), new Window(), new Window() }; var windows = new List<Window> { new Window(), new Window(), new Window(), new Window() };
@ -50,7 +50,7 @@ namespace Avalonia.Controls.UnitTests
public void Should_Only_Exit_On_Explicit_Exit() public void Should_Only_Exit_On_Explicit_Exit()
{ {
using (UnitTestApplication.Start(TestServices.StyledWindow)) using (UnitTestApplication.Start(TestServices.StyledWindow))
using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
lifetime.ShutdownMode = ShutdownMode.OnExplicitShutdown; lifetime.ShutdownMode = ShutdownMode.OnExplicitShutdown;
@ -84,7 +84,7 @@ namespace Avalonia.Controls.UnitTests
public void Should_Exit_After_MainWindow_Closed() public void Should_Exit_After_MainWindow_Closed()
{ {
using (UnitTestApplication.Start(TestServices.StyledWindow)) using (UnitTestApplication.Start(TestServices.StyledWindow))
using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
lifetime.ShutdownMode = ShutdownMode.OnMainWindowClose; lifetime.ShutdownMode = ShutdownMode.OnMainWindowClose;
@ -112,7 +112,7 @@ namespace Avalonia.Controls.UnitTests
public void Should_Exit_After_Last_Window_Closed() public void Should_Exit_After_Last_Window_Closed()
{ {
using (UnitTestApplication.Start(TestServices.StyledWindow)) using (UnitTestApplication.Start(TestServices.StyledWindow))
using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
lifetime.ShutdownMode = ShutdownMode.OnLastWindowClose; lifetime.ShutdownMode = ShutdownMode.OnLastWindowClose;
@ -142,7 +142,7 @@ namespace Avalonia.Controls.UnitTests
public void Show_Should_Add_Window_To_OpenWindows() public void Show_Should_Add_Window_To_OpenWindows()
{ {
using (UnitTestApplication.Start(TestServices.StyledWindow)) using (UnitTestApplication.Start(TestServices.StyledWindow))
using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
var window = new Window(); var window = new Window();
@ -156,7 +156,7 @@ namespace Avalonia.Controls.UnitTests
public void Window_Should_Be_Added_To_OpenWindows_Only_Once() public void Window_Should_Be_Added_To_OpenWindows_Only_Once()
{ {
using (UnitTestApplication.Start(TestServices.StyledWindow)) using (UnitTestApplication.Start(TestServices.StyledWindow))
using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
var window = new Window(); var window = new Window();
@ -174,7 +174,7 @@ namespace Avalonia.Controls.UnitTests
public void Close_Should_Remove_Window_From_OpenWindows() public void Close_Should_Remove_Window_From_OpenWindows()
{ {
using (UnitTestApplication.Start(TestServices.StyledWindow)) using (UnitTestApplication.Start(TestServices.StyledWindow))
using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
var window = new Window(); var window = new Window();
@ -197,7 +197,7 @@ namespace Avalonia.Controls.UnitTests
windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object)); windowingPlatform: new MockWindowingPlatform(() => windowImpl.Object));
using (UnitTestApplication.Start(services)) using (UnitTestApplication.Start(services))
using(var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using(var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
var window = new Window(); var window = new Window();

286
tests/Avalonia.Controls.UnitTests/GridTests.cs

@ -1,11 +1,6 @@
using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Avalonia.Controls.Primitives;
using Avalonia.Input;
using Avalonia.Platform;
using Avalonia.UnitTests;
using Moq;
using Xunit; using Xunit;
using Xunit.Abstractions; using Xunit.Abstractions;
@ -34,7 +29,6 @@ namespace Avalonia.Controls.UnitTests
private Grid CreateGrid(params (string name, GridLength width, double minWidth, double maxWidth)[] columns) private Grid CreateGrid(params (string name, GridLength width, double minWidth, double maxWidth)[] columns)
{ {
var grid = new Grid(); var grid = new Grid();
foreach (var k in columns.Select(c => new ColumnDefinition foreach (var k in columns.Select(c => new ColumnDefinition
{ {
@ -1178,6 +1172,41 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(0, grids[0].ColumnDefinitions[0].ActualWidth); Assert.Equal(0, grids[0].ColumnDefinitions[0].ActualWidth);
} }
[Fact]
public void Size_Group_Definition_Resizes_Are_Tracked()
{
var grids = new[] {
CreateGrid(("A", new GridLength(5, GridUnitType.Pixel)), (null, new GridLength())),
CreateGrid(("A", new GridLength(5, GridUnitType.Pixel)), (null, new GridLength())) };
var scope = new Grid();
foreach (var xgrids in grids)
scope.Children.Add(xgrids);
var root = new Grid();
root.UseLayoutRounding = false;
root.SetValue(Grid.IsSharedSizeScopeProperty, true);
root.Children.Add(scope);
root.Measure(new Size(50, 50));
root.Arrange(new Rect(new Point(), new Point(50, 50)));
PrintColumnDefinitions(grids[0]);
Assert.Equal(5, grids[0].ColumnDefinitions[0].ActualWidth);
Assert.Equal(5, grids[1].ColumnDefinitions[0].ActualWidth);
grids[0].ColumnDefinitions[0].Width = new GridLength(10, GridUnitType.Pixel);
foreach (Grid grid in grids)
{
grid.Measure(new Size(50, 50));
grid.Arrange(new Rect(new Point(), new Point(50, 50)));
}
PrintColumnDefinitions(grids[0]);
Assert.Equal(10, grids[0].ColumnDefinitions[0].ActualWidth);
Assert.Equal(10, grids[1].ColumnDefinitions[0].ActualWidth);
}
[Fact] [Fact]
public void Collection_Changes_Are_Tracked() public void Collection_Changes_Are_Tracked()
{ {
@ -1270,11 +1299,11 @@ namespace Avalonia.Controls.UnitTests
// grid.Measure(new Size(100, 100)); // grid.Measure(new Size(100, 100));
// grid.Arrange(new Rect(new Point(), new Point(100, 100))); // grid.Arrange(new Rect(new Point(), new Point(100, 100)));
// PrintColumnDefinitions(grid); // PrintColumnDefinitions(grid);
// NOTE: THIS IS BROKEN IN WPF // NOTE: THIS IS BROKEN IN WPF
// all in group are equal to width (MinWidth) of the sizer in the second column // all in group are equal to width (MinWidth) of the sizer in the second column
// Assert.All(grid.ColumnDefinitions.Where(cd => cd.SharedSizeGroup == "A"), cd => Assert.Equal(6 + 1 * 6, cd.ActualWidth)); // Assert.All(grid.ColumnDefinitions.Where(cd => cd.SharedSizeGroup == "A"), cd => Assert.Equal(6 + 1 * 6, cd.ActualWidth));
// NOTE: THIS IS BROKEN IN WPF // NOTE: THIS IS BROKEN IN WPF
// grid.ColumnDefinitions[2].SharedSizeGroup = null; // grid.ColumnDefinitions[2].SharedSizeGroup = null;
@ -1382,6 +1411,245 @@ namespace Avalonia.Controls.UnitTests
Assert.Equal(new Size(100, 100), grid.Bounds.Size); Assert.Equal(new Size(100, 100), grid.Bounds.Size);
} }
[Theory]
[InlineData(true)]
[InlineData(false)]
public void Changing_Column_Width_Should_Invalidate_Grid(bool setUsingAvaloniaProperty)
{
var grid = new Grid { ColumnDefinitions = ColumnDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
if (setUsingAvaloniaProperty)
grid.ColumnDefinitions[0][ColumnDefinition.WidthProperty] = new GridLength(5);
else
grid.ColumnDefinitions[0].Width = new GridLength(5);
});
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void Changing_Column_MinWidth_Should_Invalidate_Grid(bool setUsingAvaloniaProperty)
{
var grid = new Grid { ColumnDefinitions = ColumnDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
if (setUsingAvaloniaProperty)
grid.ColumnDefinitions[0][ColumnDefinition.MinWidthProperty] = 5;
else
grid.ColumnDefinitions[0].MinWidth = 5;
});
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void Changing_Column_MaxWidth_Should_Invalidate_Grid(bool setUsingAvaloniaProperty)
{
var grid = new Grid { ColumnDefinitions = ColumnDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
if (setUsingAvaloniaProperty)
grid.ColumnDefinitions[0][ColumnDefinition.MaxWidthProperty] = 5;
else
grid.ColumnDefinitions[0].MaxWidth = 5;
});
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void Changing_Row_Height_Should_Invalidate_Grid(bool setUsingAvaloniaProperty)
{
var grid = new Grid { RowDefinitions = RowDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
if (setUsingAvaloniaProperty)
grid.RowDefinitions[0][RowDefinition.HeightProperty] = new GridLength(5);
else
grid.RowDefinitions[0].Height = new GridLength(5);
});
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void Changing_Row_MinHeight_Should_Invalidate_Grid(bool setUsingAvaloniaProperty)
{
var grid = new Grid { RowDefinitions = RowDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
if (setUsingAvaloniaProperty)
grid.RowDefinitions[0][RowDefinition.MinHeightProperty] = 5;
else
grid.RowDefinitions[0].MinHeight = 5;
});
}
[Theory]
[InlineData(true)]
[InlineData(false)]
public void Changing_Row_MaxHeight_Should_Invalidate_Grid(bool setUsingAvaloniaProperty)
{
var grid = new Grid { RowDefinitions = RowDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
if (setUsingAvaloniaProperty)
grid.RowDefinitions[0][RowDefinition.MaxHeightProperty] = 5;
else
grid.RowDefinitions[0].MaxHeight = 5;
});
}
[Fact]
public void Adding_Column_Should_Invalidate_Grid()
{
var grid = new Grid { ColumnDefinitions = ColumnDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
grid.ColumnDefinitions.Add(new ColumnDefinition(new GridLength(5)));
});
}
[Fact]
public void Adding_Row_Should_Invalidate_Grid()
{
var grid = new Grid { RowDefinitions = RowDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
grid.RowDefinitions.Add(new RowDefinition(new GridLength(5)));
});
}
[Fact]
public void Replacing_Columns_Should_Invalidate_Grid()
{
var grid = new Grid { ColumnDefinitions = ColumnDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
grid.ColumnDefinitions = ColumnDefinitions.Parse("2*,1*");
});
}
[Fact]
public void Replacing_Rows_Should_Invalidate_Grid()
{
var grid = new Grid { RowDefinitions = RowDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
grid.RowDefinitions = RowDefinitions.Parse("2*,1*");
});
}
[Fact]
public void Removing_Column_Should_Invalidate_Grid()
{
var grid = new Grid { ColumnDefinitions = ColumnDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
grid.ColumnDefinitions.RemoveAt(0);
});
}
[Fact]
public void Removing_Row_Should_Invalidate_Grid()
{
var grid = new Grid { RowDefinitions = RowDefinitions.Parse("1*,1*") };
Change_Property_And_Verify_Measure_Requested(grid, () =>
{
grid.RowDefinitions.RemoveAt(0);
});
}
[Fact]
public void Removing_Child_Should_Invalidate_Grid_And_Be_Operational()
{
var grid = new Grid { ColumnDefinitions = ColumnDefinitions.Parse("*,Auto") };
grid.Children.Add(new Decorator() { [Grid.ColumnProperty] = 0 });
grid.Children.Add(new Decorator() { Width = 10, Height = 10, [Grid.ColumnProperty] = 1 });
var size = new Size(100, 100);
grid.Measure(size);
grid.Arrange(new Rect(size));
Assert.True(grid.IsMeasureValid);
Assert.True(grid.IsArrangeValid);
Assert.Equal(90, grid.Children[0].Bounds.Width);
Assert.Equal(10, grid.Children[1].Bounds.Width);
grid.Children.RemoveAt(1);
Assert.False(grid.IsMeasureValid);
Assert.False(grid.IsArrangeValid);
grid.Measure(size);
grid.Arrange(new Rect(size));
Assert.True(grid.IsMeasureValid);
Assert.True(grid.IsArrangeValid);
Assert.Equal(100, grid.Children[0].Bounds.Width);
}
[Fact]
public void Adding_Child_Should_Invalidate_Grid_And_Be_Operational()
{
var grid = new Grid { ColumnDefinitions = ColumnDefinitions.Parse("*,Auto") };
grid.Children.Add(new Decorator() { [Grid.ColumnProperty] = 0 });
var size = new Size(100, 100);
grid.Measure(size);
grid.Arrange(new Rect(size));
Assert.True(grid.IsMeasureValid);
Assert.True(grid.IsArrangeValid);
Assert.Equal(100, grid.Children[0].Bounds.Width);
grid.Children.Add(new Decorator() { Width = 10, Height = 10, [Grid.ColumnProperty] = 1 });
Assert.False(grid.IsMeasureValid);
Assert.False(grid.IsArrangeValid);
grid.Measure(size);
grid.Arrange(new Rect(size));
Assert.True(grid.IsMeasureValid);
Assert.True(grid.IsArrangeValid);
Assert.Equal(90, grid.Children[0].Bounds.Width);
Assert.Equal(10, grid.Children[1].Bounds.Width);
}
private static void Change_Property_And_Verify_Measure_Requested(Grid grid, Action change)
{
grid.Measure(new Size(100, 100));
grid.Arrange(new Rect(grid.DesiredSize));
Assert.True(grid.IsMeasureValid);
Assert.True(grid.IsArrangeValid);
change();
Assert.False(grid.IsMeasureValid);
Assert.False(grid.IsArrangeValid);
}
private class TestControl : Control private class TestControl : Control
{ {
public Size MeasureSize { get; set; } public Size MeasureSize { get; set; }

6
tests/Avalonia.ReactiveUI.UnitTests/AutoSuspendHelperTest.cs

@ -45,7 +45,7 @@ namespace Avalonia.ReactiveUI.UnitTests
public void AutoSuspendHelper_Should_Immediately_Fire_IsLaunchingNew() public void AutoSuspendHelper_Should_Immediately_Fire_IsLaunchingNew()
{ {
using (UnitTestApplication.Start(TestServices.MockWindowingPlatform)) using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
using (var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using (var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
var isLaunchingReceived = false; var isLaunchingReceived = false;
var application = AvaloniaLocator.Current.GetService<Application>(); var application = AvaloniaLocator.Current.GetService<Application>();
@ -86,7 +86,7 @@ namespace Avalonia.ReactiveUI.UnitTests
public void ShouldPersistState_Should_Fire_On_App_Exit_When_SuspensionDriver_Is_Initialized() public void ShouldPersistState_Should_Fire_On_App_Exit_When_SuspensionDriver_Is_Initialized()
{ {
using (UnitTestApplication.Start(TestServices.MockWindowingPlatform)) using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
using (var lifetime = new ClassicDesktopStyleApplicationLifetime(Application.Current)) using (var lifetime = new ClassicDesktopStyleApplicationLifetime())
{ {
var shouldPersistReceived = false; var shouldPersistReceived = false;
var application = AvaloniaLocator.Current.GetService<Application>(); var application = AvaloniaLocator.Current.GetService<Application>();
@ -105,4 +105,4 @@ namespace Avalonia.ReactiveUI.UnitTests
} }
} }
} }
} }

Loading…
Cancel
Save