diff --git a/.travis.yml b/.travis.yml index fdffaba477..51b2aaf2bc 100644 --- a/.travis.yml +++ b/.travis.yml @@ -9,7 +9,7 @@ env: - DOTNET_CLI_TELEMETRY_OPTOUT=1 mono: - 5.2.0 -dotnet: 2.0.0 +dotnet: 2.1.200 script: - ./build.sh --target "Travis" --platform "NetCoreOnly" --configuration "Release" notifications: diff --git a/Avalonia.sln b/Avalonia.sln index 88914fe188..47ee4c1ad9 100644 --- a/Avalonia.sln +++ b/Avalonia.sln @@ -76,7 +76,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup", "src\Mark EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.UnitTests", "tests\Avalonia.Markup.UnitTests\Avalonia.Markup.UnitTests.csproj", "{8EF392D5-1416-45AA-9956-7CBBC3229E8A}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BindingTest", "samples\BindingTest\BindingTest.csproj", "{08B3E6B9-1CD5-443C-9F61-6D49D1C5F162}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "BindingTest", "samples\BindingTest\BindingTest.csproj", "{08B3E6B9-1CD5-443C-9F61-6D49D1C5F162}" EndProject Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "RenderHelpers", "src\Shared\RenderHelpers\RenderHelpers.shproj", "{3C4C0CB4-0C0F-4450-A37B-148C84FF905F}" EndProject @@ -114,7 +114,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DesignerSupport.Te EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DesignerSupport.TestApp", "tests\Avalonia.DesignerSupport.TestApp\Avalonia.DesignerSupport.TestApp.csproj", "{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "VirtualizationTest", "samples\VirtualizationTest\VirtualizationTest.csproj", "{FBCAF3D0-2808-4934-8E96-3F607594517B}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "VirtualizationTest", "samples\VirtualizationTest\VirtualizationTest.csproj", "{FBCAF3D0-2808-4934-8E96-3F607594517B}" EndProject Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Interop", "Interop", "{A0CC0258-D18C-4AB3-854F-7101680FC3F9}" EndProject @@ -122,7 +122,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WindowsInteropTest", "sampl EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DotNetFrameworkRuntime", "src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj", "{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "RenderTest", "samples\RenderTest\RenderTest.csproj", "{F1FDC5B0-4654-416F-AE69-E3E9BBD87801}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RenderTest", "samples\RenderTest\RenderTest.csproj", "{F1FDC5B0-4654-416F-AE69-E3E9BBD87801}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Android", "samples\ControlCatalog.Android\ControlCatalog.Android.csproj", "{29132311-1848-4FD6-AE0C-4FF841151BD3}" EndProject @@ -146,11 +146,12 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1 build\Microsoft.Reactive.Testing.props = build\Microsoft.Reactive.Testing.props build\Moq.props = build\Moq.props build\NetCore.props = build\NetCore.props + build\NetFX.props = build\NetFX.props build\ReactiveUI.props = build\ReactiveUI.props build\Rx.props = build\Rx.props + build\SampleApp.props = build\SampleApp.props build\Serilog.props = build\Serilog.props build\SharpDX.props = build\SharpDX.props - build\SkiaSharp.Desktop.props = build\SkiaSharp.Desktop.props build\SkiaSharp.props = build\SkiaSharp.props build\Splat.props = build\Splat.props build\Sprache.props = build\Sprache.props @@ -2590,6 +2591,7 @@ Global {E2999E4A-9086-401F-898C-AEB0AD38E676} = {9B9E3891-2366-4253-A952-D08BCEB71098} {050CC912-FF49-4A8B-B534-9544017446DD} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} {F40FC0A2-1BC3-401C-BFC1-928EC4D4A9CE} = {9B9E3891-2366-4253-A952-D08BCEB71098} + {CBFD5788-567D-401B-9DFA-74E4224025A0} = {A59C4C0A-64DF-4621-B450-2BA00D6F61E2} {4ADA61C8-D191-428D-9066-EF4F0D86520F} = {4ED8B739-6F4E-4CD4-B993-545E6B5CE637} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution diff --git a/build/Base.props b/build/Base.props index 6689465338..78930156e7 100644 --- a/build/Base.props +++ b/build/Base.props @@ -2,4 +2,4 @@ - + \ No newline at end of file diff --git a/build/EmbedXaml.props b/build/EmbedXaml.props new file mode 100644 index 0000000000..219ffb2e42 --- /dev/null +++ b/build/EmbedXaml.props @@ -0,0 +1,11 @@ + + + + %(Filename) + + + Designer + + + \ No newline at end of file diff --git a/build/SampleApp.props b/build/SampleApp.props new file mode 100644 index 0000000000..3b538e4029 --- /dev/null +++ b/build/SampleApp.props @@ -0,0 +1,13 @@ + + + WinExe + + + + + + + + + diff --git a/build/SharedVersion.props b/build/SharedVersion.props new file mode 100644 index 0000000000..351583a106 --- /dev/null +++ b/build/SharedVersion.props @@ -0,0 +1,14 @@ + + + Avalonia + 0.6.2 + Copyright 2016 © The AvaloniaUI Project + https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md + https://github.com/AvaloniaUI/Avalonia/ + https://github.com/AvaloniaUI/Avalonia/ + true + CS1591 + latest + + \ No newline at end of file diff --git a/parameters.cake b/parameters.cake index e224cce151..9e6eaa9d27 100644 --- a/parameters.cake +++ b/parameters.cake @@ -115,7 +115,7 @@ public class Parameters FileZipSuffix = Version + ".zip"; ZipCoreArtifacts = ZipRoot.CombineWithFilePath("Avalonia-" + FileZipSuffix); - ZipSourceControlCatalogDesktopDirs = (DirectoryPath)context.Directory("./samples/ControlCatalog.Desktop/bin/" + DirSuffix); + ZipSourceControlCatalogDesktopDirs = (DirectoryPath)context.Directory("./samples/ControlCatalog.Desktop/bin/" + DirSuffix + "/net461"); ZipTargetControlCatalogDesktopDirs = ZipRoot.CombineWithFilePath("ControlCatalog.Desktop-" + FileZipSuffix); } } diff --git a/samples/BindingTest/BindingTest.csproj b/samples/BindingTest/BindingTest.csproj index a17fe0eed1..30d7dbb2ec 100644 --- a/samples/BindingTest/BindingTest.csproj +++ b/samples/BindingTest/BindingTest.csproj @@ -1,155 +1,33 @@ - - - + - Debug - AnyCPU - {08B3E6B9-1CD5-443C-9F61-6D49D1C5F162} - WinExe - Properties - BindingTest - BindingTest - v4.7 - 512 - true - - PackageReference + Exe + netcoreapp2.0;net461 - - AnyCPU - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - - - AnyCPU - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - - - - - - - - - - - - - - - - - Designer - - - App.xaml - - - MainWindow.xaml - - - - TestItemView.xaml - - - - - - - - - - - - Designer - - - - - {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0} - Avalonia.DotNetFrameworkRuntime - - - {3e53a01a-b331-47f3-b828-4a5717e77a24} - Avalonia.Markup.Xaml - - - {6417e941-21bc-467b-a771-0de389353ce6} - Avalonia.Markup - - - {d211e587-d8bc-45b9-95a4-f297c8fa5200} - Avalonia.Animation - - - {b09b78d8-9b26-48b0-9149-d64a2f120f3f} - Avalonia.Base - - - {d2221c82-4a25-4583-9b43-d791e3f6820c} - Avalonia.Controls - - - {799a7bb5-3c2c-48b6-85a7-406a12c420da} - Avalonia.DesignerSupport - - - {7062ae20-5dcc-4442-9645-8195bdece63e} - Avalonia.Diagnostics - - - {62024b2d-53eb-4638-b26b-85eeaa54866e} - Avalonia.Input - - - {6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b} - Avalonia.Interactivity - - - {42472427-4774-4c81-8aff-9f27b8e31721} - Avalonia.Layout - - - {b61b66a3-b82d-4875-8001-89d3394fe0c9} - Avalonia.Logging.Serilog - - - {6417b24e-49c2-4985-8db2-3ab9d898ec91} - Avalonia.ReactiveUI - - - {eb582467-6abb-43a1-b052-e981ba910e3a} - Avalonia.Visuals - - - {f1baa01a-f176-4c6a-b39d-5b40bb1b148f} - Avalonia.Styling - - - {3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f} - Avalonia.Themes.Default - - - {3e908f67-5543-4879-a1dc-08eace79b3cd} - Avalonia.Direct2D1 - - - {811a76cf-1cf6-440f-963b-bbe31bd72a82} - Avalonia.Win32 - + + + + + + + + + + + + + + + + + + + + + - + + diff --git a/samples/BindingTest/MainWindow.xaml b/samples/BindingTest/MainWindow.xaml index 4eb45e07c5..6b80225686 100644 --- a/samples/BindingTest/MainWindow.xaml +++ b/samples/BindingTest/MainWindow.xaml @@ -1,7 +1,10 @@ + xmlns:local="clr-namespace:BindingTest" + Title="AvaloniaUI Bindings Test" + Width="800" + Height="600"> \ No newline at end of file diff --git a/src/Avalonia.Themes.Default/Expander.xaml b/src/Avalonia.Themes.Default/Expander.xaml index 5e05dcf608..0bea0c9763 100644 --- a/src/Avalonia.Themes.Default/Expander.xaml +++ b/src/Avalonia.Themes.Default/Expander.xaml @@ -18,8 +18,9 @@ IsVisible="{TemplateBinding IsExpanded}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" - HorizontalAlignment="Stretch" - VerticalAlignment="Stretch" /> + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" + Padding="{TemplateBinding Padding}" /> @@ -36,8 +37,9 @@ IsVisible="{TemplateBinding IsExpanded}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" - HorizontalAlignment="Stretch" - VerticalAlignment="Stretch" /> + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" + Padding="{TemplateBinding Padding}" /> @@ -54,8 +56,9 @@ IsVisible="{TemplateBinding IsExpanded}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" - HorizontalAlignment="Stretch" - VerticalAlignment="Stretch" /> + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" + Padding="{TemplateBinding Padding}" /> @@ -72,8 +75,9 @@ IsVisible="{TemplateBinding IsExpanded}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" - HorizontalAlignment="Stretch" - VerticalAlignment="Stretch" /> + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" + Padding="{TemplateBinding Padding}" /> @@ -94,7 +98,10 @@ Grid.Column="1" Background="Transparent" Content="{TemplateBinding Content}" - VerticalAlignment="Center" /> + VerticalAlignment="Center" + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" + Padding="{TemplateBinding Padding}"/> diff --git a/src/Avalonia.Themes.Default/ListBoxItem.xaml b/src/Avalonia.Themes.Default/ListBoxItem.xaml index a0405f2875..fc2600c1a9 100644 --- a/src/Avalonia.Themes.Default/ListBoxItem.xaml +++ b/src/Avalonia.Themes.Default/ListBoxItem.xaml @@ -9,7 +9,9 @@ BorderThickness="{TemplateBinding BorderThickness}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" - Padding="{TemplateBinding Padding}"/> + Padding="{TemplateBinding Padding}" + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}"/> diff --git a/src/Avalonia.Themes.Default/Properties/AssemblyInfo.cs b/src/Avalonia.Themes.Default/Properties/AssemblyInfo.cs deleted file mode 100644 index 3657673618..0000000000 --- a/src/Avalonia.Themes.Default/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,6 +0,0 @@ -// 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.Reflection; - -[assembly: AssemblyTitle("Avalonia.Themes.Default")] diff --git a/src/Avalonia.Themes.Default/RepeatButton.xaml b/src/Avalonia.Themes.Default/RepeatButton.xaml index 872f390ac5..001c5c2f23 100644 --- a/src/Avalonia.Themes.Default/RepeatButton.xaml +++ b/src/Avalonia.Themes.Default/RepeatButton.xaml @@ -25,7 +25,7 @@ Padding="{TemplateBinding Padding}" TextBlock.Foreground="{TemplateBinding Foreground}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" - VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" /> + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/> diff --git a/src/Avalonia.Themes.Default/TabStripItem.xaml b/src/Avalonia.Themes.Default/TabStripItem.xaml index 408cfaa3d7..8aa03d5bd2 100644 --- a/src/Avalonia.Themes.Default/TabStripItem.xaml +++ b/src/Avalonia.Themes.Default/TabStripItem.xaml @@ -11,6 +11,8 @@ BorderThickness="{TemplateBinding BorderThickness}" ContentTemplate="{TemplateBinding ContentTemplate}" Content="{TemplateBinding Content}" + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Padding="{TemplateBinding Padding}"/> diff --git a/src/Avalonia.Themes.Default/TextBox.xaml b/src/Avalonia.Themes.Default/TextBox.xaml index e228aebf58..c57e5b792d 100644 --- a/src/Avalonia.Themes.Default/TextBox.xaml +++ b/src/Avalonia.Themes.Default/TextBox.xaml @@ -11,7 +11,7 @@ BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> - + - + + TextWrapping="{TemplateBinding TextWrapping}" + PasswordChar="{TemplateBinding PasswordChar}"/> diff --git a/src/Avalonia.Themes.Default/TreeViewItem.xaml b/src/Avalonia.Themes.Default/TreeViewItem.xaml index 5fb1dfb73d..3a8fe344c5 100644 --- a/src/Avalonia.Themes.Default/TreeViewItem.xaml +++ b/src/Avalonia.Themes.Default/TreeViewItem.xaml @@ -13,6 +13,8 @@ BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Content="{TemplateBinding Header}" + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" Padding="{TemplateBinding Padding}" TemplatedControl.IsTemplateFocusTarget="True" Grid.Column="1"/> diff --git a/src/Avalonia.Themes.Default/Window.xaml b/src/Avalonia.Themes.Default/Window.xaml index d19bf41c4d..f36e091e55 100644 --- a/src/Avalonia.Themes.Default/Window.xaml +++ b/src/Avalonia.Themes.Default/Window.xaml @@ -6,10 +6,12 @@ - + Content="{TemplateBinding Content}" + Margin="{TemplateBinding Padding}" + HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" + VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}"/> diff --git a/src/Avalonia.Visuals/Avalonia.Visuals.csproj b/src/Avalonia.Visuals/Avalonia.Visuals.csproj index fe18b0e446..f320644cd0 100644 --- a/src/Avalonia.Visuals/Avalonia.Visuals.csproj +++ b/src/Avalonia.Visuals/Avalonia.Visuals.csproj @@ -1,39 +1,11 @@  netstandard2.0 - false Avalonia - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\Avalonia.Visuals.xml - CS1591 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\Avalonia.Visuals.xml - CS1591 - true - - - - - Properties\SharedAssemblyInfo.cs - - + \ No newline at end of file diff --git a/src/Avalonia.Visuals/Matrix.cs b/src/Avalonia.Visuals/Matrix.cs index b09ea2b68c..9ed5923109 100644 --- a/src/Avalonia.Visuals/Matrix.cs +++ b/src/Avalonia.Visuals/Matrix.cs @@ -11,7 +11,7 @@ namespace Avalonia /// /// A 2x3 matrix. /// - public struct Matrix + public readonly struct Matrix { private readonly double _m11; private readonly double _m12; diff --git a/src/Avalonia.Visuals/Media/Color.cs b/src/Avalonia.Visuals/Media/Color.cs index 82cc19347a..aacce3fdce 100644 --- a/src/Avalonia.Visuals/Media/Color.cs +++ b/src/Avalonia.Visuals/Media/Color.cs @@ -11,7 +11,7 @@ namespace Avalonia.Media /// /// An ARGB color. /// - public struct Color + public readonly struct Color { /// /// Gets or sets the Alpha component of the color. diff --git a/src/Avalonia.Visuals/Media/DrawingContext.cs b/src/Avalonia.Visuals/Media/DrawingContext.cs index 1aa3fd21de..1d25224b8d 100644 --- a/src/Avalonia.Visuals/Media/DrawingContext.cs +++ b/src/Avalonia.Visuals/Media/DrawingContext.cs @@ -19,7 +19,7 @@ namespace Avalonia.Media ? new Stack() : TransformStackPool.Pop(); - struct TransformContainer + readonly struct TransformContainer { public readonly Matrix LocalTransform; public readonly Matrix ContainerTransform; @@ -147,7 +147,7 @@ namespace Avalonia.Media } } - public struct PushedState : IDisposable + public readonly struct PushedState : IDisposable { private readonly int _level; private readonly DrawingContext _context; diff --git a/src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs b/src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs index 015486c6a4..b55ca251a6 100644 --- a/src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs +++ b/src/Avalonia.Visuals/Media/Immutable/ImmutableSolidColorBrush.cs @@ -6,7 +6,7 @@ namespace Avalonia.Media.Immutable /// /// Fills an area with a solid color. /// - public struct ImmutableSolidColorBrush : ISolidColorBrush + public readonly struct ImmutableSolidColorBrush : ISolidColorBrush { /// /// Initializes a new instance of the class. diff --git a/src/Avalonia.Visuals/Point.cs b/src/Avalonia.Visuals/Point.cs index 62be3bf276..34070ac71f 100644 --- a/src/Avalonia.Visuals/Point.cs +++ b/src/Avalonia.Visuals/Point.cs @@ -11,7 +11,7 @@ namespace Avalonia /// /// Defines a point. /// - public struct Point + public readonly struct Point { /// /// The X position. diff --git a/src/Avalonia.Visuals/Properties/AssemblyInfo.cs b/src/Avalonia.Visuals/Properties/AssemblyInfo.cs index 900746d05a..05c3d7e62a 100644 --- a/src/Avalonia.Visuals/Properties/AssemblyInfo.cs +++ b/src/Avalonia.Visuals/Properties/AssemblyInfo.cs @@ -5,7 +5,6 @@ using System.Reflection; using System.Runtime.CompilerServices; using Avalonia.Metadata; -[assembly: AssemblyTitle("Avalonia.Visuals")] [assembly: InternalsVisibleTo("Avalonia.Visuals.UnitTests")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Animation")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Media")] diff --git a/src/Avalonia.Visuals/Rect.cs b/src/Avalonia.Visuals/Rect.cs index 73021ca29a..d28fff0216 100644 --- a/src/Avalonia.Visuals/Rect.cs +++ b/src/Avalonia.Visuals/Rect.cs @@ -11,7 +11,7 @@ namespace Avalonia /// /// Defines a rectangle. /// - public struct Rect + public readonly struct Rect { /// /// An empty rectangle. diff --git a/src/Avalonia.Visuals/RelativePoint.cs b/src/Avalonia.Visuals/RelativePoint.cs index e4d7ea05cb..5d3cb23a90 100644 --- a/src/Avalonia.Visuals/RelativePoint.cs +++ b/src/Avalonia.Visuals/RelativePoint.cs @@ -28,7 +28,7 @@ namespace Avalonia /// /// Defines a point that may be defined relative to a containing element. /// - public struct RelativePoint : IEquatable + public readonly struct RelativePoint : IEquatable { /// /// A point at the top left of the containing element. @@ -45,7 +45,7 @@ namespace Avalonia /// public static readonly RelativePoint BottomRight = new RelativePoint(1, 1, RelativeUnit.Relative); - private Point _point; + private readonly Point _point; private readonly RelativeUnit _unit; diff --git a/src/Avalonia.Visuals/RelativeRect.cs b/src/Avalonia.Visuals/RelativeRect.cs index ad42e30057..0afe74f0be 100644 --- a/src/Avalonia.Visuals/RelativeRect.cs +++ b/src/Avalonia.Visuals/RelativeRect.cs @@ -11,7 +11,7 @@ namespace Avalonia /// /// Defines a rectangle that may be defined relative to a containing element. /// - public struct RelativeRect : IEquatable + public readonly struct RelativeRect : IEquatable { private static readonly char[] PercentChar = { '%' }; diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs index dfd45fba9c..f3dbfbd8fb 100644 --- a/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs +++ b/src/Avalonia.Visuals/Rendering/SceneGraph/DeferredDrawingContextImpl.cs @@ -320,7 +320,7 @@ namespace Avalonia.Rendering.SceneGraph } } - public struct UpdateState : IDisposable + public readonly struct UpdateState : IDisposable { public UpdateState( DeferredDrawingContextImpl owner, diff --git a/src/Avalonia.Visuals/Size.cs b/src/Avalonia.Visuals/Size.cs index b6889af6f0..50a3973a5c 100644 --- a/src/Avalonia.Visuals/Size.cs +++ b/src/Avalonia.Visuals/Size.cs @@ -11,7 +11,7 @@ namespace Avalonia /// /// Defines a size. /// - public struct Size + public readonly struct Size { /// /// A size representing infinity. diff --git a/src/Avalonia.Visuals/Thickness.cs b/src/Avalonia.Visuals/Thickness.cs index 43a5fed9e7..759abd5943 100644 --- a/src/Avalonia.Visuals/Thickness.cs +++ b/src/Avalonia.Visuals/Thickness.cs @@ -11,7 +11,7 @@ namespace Avalonia /// /// Describes the thickness of a frame around a rectangle. /// - public struct Thickness + public readonly struct Thickness { /// /// The thickness on the left. diff --git a/src/Avalonia.Visuals/Vector.cs b/src/Avalonia.Visuals/Vector.cs index c4545b8e5c..acde49a84a 100644 --- a/src/Avalonia.Visuals/Vector.cs +++ b/src/Avalonia.Visuals/Vector.cs @@ -10,7 +10,7 @@ namespace Avalonia /// /// Defines a vector. /// - public struct Vector + public readonly struct Vector { /// /// The X vector. diff --git a/src/Avalonia.Visuals/VisualTree/TransformedBounds.cs b/src/Avalonia.Visuals/VisualTree/TransformedBounds.cs index 435ca85a05..f8356bbcd6 100644 --- a/src/Avalonia.Visuals/VisualTree/TransformedBounds.cs +++ b/src/Avalonia.Visuals/VisualTree/TransformedBounds.cs @@ -8,7 +8,7 @@ namespace Avalonia.VisualTree /// /// Holds information about the bounds of a control, together with a transform and a clip. /// - public struct TransformedBounds + public readonly struct TransformedBounds { /// /// Initializes a new instance of the struct. diff --git a/src/Directory.Build.props b/src/Directory.Build.props new file mode 100644 index 0000000000..7325bab2a3 --- /dev/null +++ b/src/Directory.Build.props @@ -0,0 +1,3 @@ + + + \ No newline at end of file diff --git a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj index f1b990f349..ef043959ad 100644 --- a/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj +++ b/src/Gtk/Avalonia.Gtk3/Avalonia.Gtk3.csproj @@ -1,30 +1,9 @@  netstandard2.0 - false - - - true - full - false - bin\Debug\ - TRACE;DEBUG;GTK3_PINVOKE - prompt - 4 - true - - - pdbonly - true - bin\Release\ - TRACE;GTK3_PINVOKE - prompt - 4 true + $(DefineConstants);GTK3_PINVOKE - - - diff --git a/src/Gtk/Avalonia.Gtk3/Properties/AssemblyInfo.cs b/src/Gtk/Avalonia.Gtk3/Properties/AssemblyInfo.cs index 034b73f699..a27d631ee0 100644 --- a/src/Gtk/Avalonia.Gtk3/Properties/AssemblyInfo.cs +++ b/src/Gtk/Avalonia.Gtk3/Properties/AssemblyInfo.cs @@ -5,8 +5,6 @@ using Avalonia.Platform; // General Information about an assembly is controlled through the following // set of attributes. Change these attribute values to modify the information // associated with an assembly. -[assembly: AssemblyTitle("Avalonia.Gtk3")] - [assembly: ExportWindowingSubsystem(OperatingSystemType.WinNT, 2, "GTK3", typeof(Gtk3Platform), nameof(Gtk3Platform.Initialize))] [assembly: ExportWindowingSubsystem(OperatingSystemType.Linux, 1, "GTK3", typeof(Gtk3Platform), nameof(Gtk3Platform.Initialize))] [assembly: ExportWindowingSubsystem(OperatingSystemType.OSX, 2, "GTK3", typeof(Gtk3Platform), nameof(Gtk3Platform.Initialize))] \ No newline at end of file diff --git a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs index 0ebfea998a..94537d3475 100644 --- a/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/WindowBaseImpl.cs @@ -241,7 +241,7 @@ namespace Avalonia.Gtk3 return true; } - void ConnectEvent(string name, Native.D.signal_onevent handler) + protected void ConnectEvent(string name, Native.D.signal_onevent handler) => Disposables.Add(Signal.Connect(GtkWidget, name, handler)); void Connect(string name, T handler) => Disposables.Add(Signal.Connect(GtkWidget, name, handler)); diff --git a/src/Gtk/Avalonia.Gtk3/WindowImpl.cs b/src/Gtk/Avalonia.Gtk3/WindowImpl.cs index ac03816b02..bae34db6f3 100644 --- a/src/Gtk/Avalonia.Gtk3/WindowImpl.cs +++ b/src/Gtk/Avalonia.Gtk3/WindowImpl.cs @@ -1,18 +1,34 @@ using System; -using System.Linq.Expressions; using Avalonia.Controls; using Avalonia.Gtk3.Interop; using Avalonia.Platform; -using System.Runtime.InteropServices; namespace Avalonia.Gtk3 { class WindowImpl : WindowBaseImpl, IWindowImpl { + private WindowState _lastWindowState; + public WindowImpl() : base(Native.GtkWindowNew(GtkWindowType.TopLevel)) { } + protected unsafe override bool OnStateChanged(IntPtr w, IntPtr pev, IntPtr userData) + { + var windowStateEvent = (GdkEventWindowState*)pev; + var newWindowState = windowStateEvent->new_window_state; + var windowState = newWindowState.HasFlag(GdkWindowState.Iconified) ? WindowState.Minimized + : (newWindowState.HasFlag(GdkWindowState.Maximized) ? WindowState.Maximized : WindowState.Normal); + + if (windowState != _lastWindowState) + { + _lastWindowState = windowState; + WindowStateChanged?.Invoke(windowState); + } + + return base.OnStateChanged(w, pev, userData); + } + public void SetTitle(string title) { using (var t = new Utf8Buffer(title)) diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj b/src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj index 466b47f7a0..fb1fbdaf93 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj +++ b/src/Linux/Avalonia.LinuxFramebuffer/Avalonia.LinuxFramebuffer.csproj @@ -10,5 +10,5 @@ - + \ No newline at end of file diff --git a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj index e388a49a6e..2d3a43a909 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj +++ b/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj @@ -3,7 +3,6 @@ netstandard2.0 False false - false true @@ -26,9 +25,6 @@ CS1591 - - Properties\SharedAssemblyInfo.cs - diff --git a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github index faa952f3a0..cdf46d7892 160000 --- a/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github +++ b/src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github @@ -1 +1 @@ -Subproject commit faa952f3a05b4bdf2986d686f4154b1ab084508a +Subproject commit cdf46d7892def8a6ba29f12a9339147377f7cf5c diff --git a/src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs b/src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs index 0b42bedfa8..1b0e056baf 100644 --- a/src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs +++ b/src/Markup/Avalonia.Markup.Xaml/Properties/AssemblyInfo.cs @@ -5,7 +5,6 @@ using System.Reflection; using Avalonia.Metadata; using System.Runtime.CompilerServices; -[assembly: AssemblyTitle("Avalonia.Markup.Xaml")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Xaml.Data")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Xaml.MarkupExtensions")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup.Xaml.Styling")] diff --git a/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj b/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj index a6d3c3336f..a3b7d07784 100644 --- a/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj +++ b/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj @@ -1,35 +1,7 @@  netstandard2.0 - false - - true - full - false - bin\Debug\ - DEBUG;TRACE - prompt - 4 - bin\Debug\Avalonia.Markup.xml - CS1591 - - - pdbonly - true - bin\Release\ - TRACE - prompt - 4 - bin\Release\Avalonia.Markup.xml - CS1591 - true - - - - Properties\SharedAssemblyInfo.cs - - diff --git a/src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs b/src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs index dd8c0a6bd3..15c0be673a 100644 --- a/src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs +++ b/src/Markup/Avalonia.Markup/Properties/AssemblyInfo.cs @@ -5,6 +5,5 @@ using System.Reflection; using Avalonia.Metadata; using System.Runtime.CompilerServices; -[assembly: AssemblyTitle("Avalonia.Markup")] [assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Markup")] [assembly: InternalsVisibleTo("Avalonia.Markup.UnitTests")] diff --git a/src/OSX/Avalonia.MonoMac/Avalonia.MonoMac.csproj b/src/OSX/Avalonia.MonoMac/Avalonia.MonoMac.csproj index c31c131ea9..e675b43389 100644 --- a/src/OSX/Avalonia.MonoMac/Avalonia.MonoMac.csproj +++ b/src/OSX/Avalonia.MonoMac/Avalonia.MonoMac.csproj @@ -2,10 +2,8 @@ netstandard2.0 True - false - diff --git a/src/OSX/Avalonia.MonoMac/WindowImpl.cs b/src/OSX/Avalonia.MonoMac/WindowImpl.cs index 43d6918112..a2f8df6791 100644 --- a/src/OSX/Avalonia.MonoMac/WindowImpl.cs +++ b/src/OSX/Avalonia.MonoMac/WindowImpl.cs @@ -12,10 +12,24 @@ namespace Avalonia.MonoMac public bool IsResizable = true; public CGRect? UndecoratedLastUnmaximizedFrame; + private WindowState _lastWindowState; + public WindowImpl() { UpdateStyle(); Window.SetCanBecomeKeyAndMain(); + + Window.DidResize += delegate + { + var windowState = Window.IsMiniaturized ? WindowState.Minimized + : (IsZoomed ? WindowState.Maximized : WindowState.Normal); + + if (windowState != _lastWindowState) + { + _lastWindowState = windowState; + WindowStateChanged?.Invoke(windowState); + } + }; } public WindowState WindowState diff --git a/src/Shared/RenderHelpers/ArcToHelper.cs b/src/Shared/RenderHelpers/ArcToHelper.cs index 9da47909cb..2457606f9d 100644 --- a/src/Shared/RenderHelpers/ArcToHelper.cs +++ b/src/Shared/RenderHelpers/ArcToHelper.cs @@ -982,7 +982,7 @@ namespace Avalonia.RenderHelpers /// At some point I did not trust the WPF Matrix struct, and wrote my own simple one -_- /// This is supposed to be replaced with proper WPF Matrices everywhere /// - private struct SimpleMatrix + private readonly struct SimpleMatrix { private readonly double _a, _b, _c, _d; diff --git a/src/Skia/Avalonia.Skia/Avalonia.Skia.csproj b/src/Skia/Avalonia.Skia/Avalonia.Skia.csproj index f5ed89d154..03618e00f5 100644 --- a/src/Skia/Avalonia.Skia/Avalonia.Skia.csproj +++ b/src/Skia/Avalonia.Skia/Avalonia.Skia.csproj @@ -1,17 +1,11 @@  netstandard2.0 - false Avalonia.Skia Avalonia.Skia true - true + true - - - Properties\SharedAssemblyInfo.cs - - @@ -21,6 +15,7 @@ + - + \ No newline at end of file diff --git a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj index a84c373886..426a9a85a3 100644 --- a/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj +++ b/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj @@ -1,12 +1,8 @@  netstandard2.0 - false - - Properties\SharedAssemblyInfo.cs - UnmanagedMethods.cs diff --git a/src/Windows/Avalonia.Direct2D1/OptionalDispose.cs b/src/Windows/Avalonia.Direct2D1/OptionalDispose.cs index cd3eee8d25..e302e71102 100644 --- a/src/Windows/Avalonia.Direct2D1/OptionalDispose.cs +++ b/src/Windows/Avalonia.Direct2D1/OptionalDispose.cs @@ -2,7 +2,7 @@ namespace Avalonia.Direct2D1 { - public struct OptionalDispose : IDisposable where T : IDisposable + public readonly struct OptionalDispose : IDisposable where T : IDisposable { private readonly bool _dispose; diff --git a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs index c1c5b24048..a09d5c2d1c 100644 --- a/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs +++ b/src/Windows/Avalonia.Direct2D1/Properties/AssemblyInfo.cs @@ -5,7 +5,6 @@ using System.Reflection; using Avalonia.Platform; using Avalonia.Direct2D1; -[assembly: AssemblyTitle("Avalonia.Direct2D1")] [assembly: ExportRenderingSubsystem(OperatingSystemType.WinNT, 1, "Direct2D1", typeof(Direct2D1Platform), nameof(Direct2D1Platform.Initialize), typeof(Direct2DChecker))] diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs index fef0ef747d..a48d851e00 100644 --- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs +++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs @@ -1211,27 +1211,21 @@ namespace Avalonia.Win32.Interop [Flags] public enum OpenFileNameFlags { - OFN_ALLOWMULTISELECT = 0x00000200, - OFN_EXPLORER = 0x00080000, - OFN_HIDEREADONLY = 0x00000004, - OFN_NOREADONLYRETURN = 0x00008000, - OFN_OVERWRITEPROMPT = 0x00000002 - } - public enum HRESULT : long + public enum HRESULT : uint { S_FALSE = 0x0001, S_OK = 0x0000, E_INVALIDARG = 0x80070057, E_OUTOFMEMORY = 0x8007000E, E_NOTIMPL = 0x80004001, - E_UNEXPECTED = 0x8000FFFF, + E_UNEXPECTED = 0x8000FFFF } public enum Icons diff --git a/src/Windows/Avalonia.Win32/OleContext.cs b/src/Windows/Avalonia.Win32/OleContext.cs index 085c0f8ea9..d454c797fa 100644 --- a/src/Windows/Avalonia.Win32/OleContext.cs +++ b/src/Windows/Avalonia.Win32/OleContext.cs @@ -1,4 +1,5 @@ using System; +using System.ComponentModel; using System.Threading; using Avalonia.Platform; using Avalonia.Threading; @@ -26,8 +27,11 @@ namespace Avalonia.Win32 private OleContext() { - if (UnmanagedMethods.OleInitialize(IntPtr.Zero) != UnmanagedMethods.HRESULT.S_OK) - throw new SystemException("Failed to initialize OLE"); + UnmanagedMethods.HRESULT res = UnmanagedMethods.OleInitialize(IntPtr.Zero); + + if (res != UnmanagedMethods.HRESULT.S_OK && + res != UnmanagedMethods.HRESULT.S_FALSE /*already initialized*/) + throw new Win32Exception((int)res, "Failed to initialize OLE"); } private static bool IsValidOleThread() diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index 399a09ea6c..36e9cbb515 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -34,6 +34,7 @@ namespace Avalonia.Win32 private bool _resizable = true; private double _scaling = 1; private WindowState _showWindowState; + private WindowState _lastWindowState; private FramebufferManager _framebuffer; private OleDropTarget _dropTarget; private Size _minSize; @@ -247,19 +248,13 @@ namespace Avalonia.Win32 return; } - var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE); + var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE); - var systemDecorationStyles = UnmanagedMethods.WindowStyles.WS_OVERLAPPED - | UnmanagedMethods.WindowStyles.WS_CAPTION - | UnmanagedMethods.WindowStyles.WS_SYSMENU - | UnmanagedMethods.WindowStyles.WS_MINIMIZEBOX - | UnmanagedMethods.WindowStyles.WS_MAXIMIZEBOX; - - style |= systemDecorationStyles; + style |= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW; if (!value) { - style ^= systemDecorationStyles; + style ^= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW; } UnmanagedMethods.RECT windowRect; @@ -295,6 +290,21 @@ namespace Avalonia.Win32 UnmanagedMethods.SetWindowPosFlags.SWP_NOZORDER | UnmanagedMethods.SetWindowPosFlags.SWP_NOACTIVATE); _decorated = value; + + if(_decorated) + { + if (_resizable) + { + // If we switch decorations back on we need to restore WS_SizeFrame. + _resizable = false; + CanResize(true); + } + else + { + _resizable = true; + CanResize(false); + } + } } public void Invalidate(Rect rect) @@ -619,14 +629,25 @@ namespace Avalonia.Win32 return IntPtr.Zero; case UnmanagedMethods.WindowsMessage.WM_SIZE: + var size = (UnmanagedMethods.SizeCommand)wParam; + if (Resized != null && - (wParam == (IntPtr)UnmanagedMethods.SizeCommand.Restored || - wParam == (IntPtr)UnmanagedMethods.SizeCommand.Maximized)) + (size == UnmanagedMethods.SizeCommand.Restored || + size == UnmanagedMethods.SizeCommand.Maximized)) { var clientSize = new Size(ToInt32(lParam) & 0xffff, ToInt32(lParam) >> 16); Resized(clientSize / Scaling); } + var windowState = size == SizeCommand.Maximized ? WindowState.Maximized + : (size == SizeCommand.Minimized ? WindowState.Minimized : WindowState.Normal); + + if (windowState != _lastWindowState) + { + _lastWindowState = windowState; + WindowStateChanged?.Invoke(windowState); + } + return IntPtr.Zero; case UnmanagedMethods.WindowsMessage.WM_SYSCOMMAND: @@ -675,6 +696,7 @@ namespace Avalonia.Win32 (Screen as ScreenImpl)?.InvalidateScreensCache(); return IntPtr.Zero; } + #if USE_MANAGED_DRAG if (_managedDrag.PreprocessInputEvent(ref e)) @@ -884,14 +906,18 @@ namespace Avalonia.Win32 return; } - var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE); - - if (value) - style |= UnmanagedMethods.WindowStyles.WS_SIZEFRAME; - else - style &= ~(UnmanagedMethods.WindowStyles.WS_SIZEFRAME); - - UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE, (uint)style); + if (_decorated) + { + var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE); + + if (value) + style |= UnmanagedMethods.WindowStyles.WS_SIZEFRAME; + else + style &= ~(UnmanagedMethods.WindowStyles.WS_SIZEFRAME); + + UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE, (uint)style); + } + _resizable = value; } } diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Attached.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Attached.cs index ab2a2d899d..02600f5e00 100644 --- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Attached.cs +++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Attached.cs @@ -24,10 +24,27 @@ namespace Avalonia.Base.UnitTests Assert.Throws(() => target.SetValue(Class2.FooProperty, "throw")); } - private class Class1 : AvaloniaObject + [Fact] + public void AvaloniaProperty_Initialized_Is_Called_For_Attached_Property() + { + bool raised = false; + + using (Class1.FooProperty.Initialized.Subscribe(x => raised = true)) + { + new Class3(); + } + + Assert.True(raised); + } + + private class Base : AvaloniaObject + { + } + + private class Class1 : Base { public static readonly AttachedProperty FooProperty = - AvaloniaProperty.RegisterAttached( + AvaloniaProperty.RegisterAttached( "Foo", "foodefault", validate: ValidateFoo); @@ -43,10 +60,14 @@ namespace Avalonia.Base.UnitTests } } - private class Class2 : AvaloniaObject + private class Class2 : Base { public static readonly AttachedProperty FooProperty = Class1.FooProperty.AddOwner(); } + + private class Class3 : Base + { + } } } diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Inheritance.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Inheritance.cs index 5bd888eeb4..ef6e03a60b 100644 --- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Inheritance.cs +++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Inheritance.cs @@ -38,6 +38,26 @@ namespace Avalonia.Base.UnitTests Assert.True(raised); } + [Fact] + public void Setting_InheritanceParent_Raises_PropertyChanged_For_Attached_Property_When_Value_Changed_In_Parent() + { + bool raised = false; + + Class1 parent = new Class1(); + parent.SetValue(AttachedOwner.AttachedProperty, "changed"); + + Class2 child = new Class2(); + child.PropertyChanged += (s, e) => + raised = s == child && + e.Property == AttachedOwner.AttachedProperty && + (string)e.OldValue == null && + (string)e.NewValue == "changed"; + + child.Parent = parent; + + Assert.True(raised); + } + [Fact] public void Setting_InheritanceParent_Doesnt_Raise_PropertyChanged_When_Local_Value_Set() { @@ -75,6 +95,26 @@ namespace Avalonia.Base.UnitTests Assert.True(raised); } + [Fact] + public void Setting_Value_Of_Attached_Property_In_InheritanceParent_Raises_PropertyChanged() + { + bool raised = false; + + Class1 parent = new Class1(); + + Class2 child = new Class2(); + child.PropertyChanged += (s, e) => + raised = s == child && + e.Property == AttachedOwner.AttachedProperty && + (string)e.OldValue == null && + (string)e.NewValue == "changed"; + child.Parent = parent; + + parent.SetValue(AttachedOwner.AttachedProperty, "changed"); + + Assert.True(raised); + } + private class Class1 : AvaloniaObject { public static readonly StyledProperty FooProperty = @@ -97,5 +137,11 @@ namespace Avalonia.Base.UnitTests set { InheritanceParent = value; } } } + + private class AttachedOwner : AvaloniaObject + { + public static readonly AttachedProperty AttachedProperty = + AvaloniaProperty.RegisterAttached("Attached", inherits: true); + } } } diff --git a/tests/Avalonia.Base.UnitTests/Utilities/StringTokenizerTests.cs b/tests/Avalonia.Base.UnitTests/Utilities/StringTokenizerTests.cs new file mode 100644 index 0000000000..4f94b1ca80 --- /dev/null +++ b/tests/Avalonia.Base.UnitTests/Utilities/StringTokenizerTests.cs @@ -0,0 +1,69 @@ +using System; +using Avalonia.Utilities; +using Xunit; + +namespace Avalonia.Base.UnitTests.Utilities +{ + public class StringTokenizerTests + { + [Fact] + public void ReadInt32_Reads_Values() + { + var target = new StringTokenizer("123,456"); + + Assert.Equal(123, target.ReadInt32()); + Assert.Equal(456, target.ReadInt32()); + Assert.Throws(() => target.ReadInt32()); + } + + [Fact] + public void ReadDouble_Reads_Values() + { + var target = new StringTokenizer("12.3,45.6"); + + Assert.Equal(12.3, target.ReadDouble()); + Assert.Equal(45.6, target.ReadDouble()); + Assert.Throws(() => target.ReadDouble()); + } + + [Fact] + public void TryReadInt32_Reads_Values() + { + var target = new StringTokenizer("123,456"); + + Assert.True(target.TryReadInt32(out var value)); + Assert.Equal(123, value); + Assert.True(target.TryReadInt32(out value)); + Assert.Equal(456, value); + Assert.False(target.TryReadInt32(out value)); + } + + [Fact] + public void TryReadInt32_Doesnt_Throw() + { + var target = new StringTokenizer("abc"); + + Assert.False(target.TryReadInt32(out var value)); + } + + [Fact] + public void TryReadDouble_Reads_Values() + { + var target = new StringTokenizer("12.3,45.6"); + + Assert.True(target.TryReadDouble(out var value)); + Assert.Equal(12.3, value); + Assert.True(target.TryReadDouble(out value)); + Assert.Equal(45.6, value); + Assert.False(target.TryReadDouble(out value)); + } + + [Fact] + public void TryReadDouble_Doesnt_Throw() + { + var target = new StringTokenizer("abc"); + + Assert.False(target.TryReadDouble(out var value)); + } + } +} diff --git a/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj b/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj index fe7e48e085..3706a50525 100644 --- a/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj +++ b/tests/Avalonia.Controls.UnitTests/Avalonia.Controls.UnitTests.csproj @@ -1,6 +1,7 @@  netcoreapp2.0 + latest Library diff --git a/tests/Avalonia.Controls.UnitTests/GridLayoutTests.cs b/tests/Avalonia.Controls.UnitTests/GridLayoutTests.cs new file mode 100644 index 0000000000..fbb90de505 --- /dev/null +++ b/tests/Avalonia.Controls.UnitTests/GridLayoutTests.cs @@ -0,0 +1,173 @@ +using System.Collections.Generic; +using System.Diagnostics.CodeAnalysis; +using System.Linq; +using Avalonia.Controls.Utils; +using Xunit; + +namespace Avalonia.Controls.UnitTests +{ + public class GridLayoutTests + { + private const double Inf = double.PositiveInfinity; + + [Theory] + [InlineData("100, 200, 300", 0d, 0d, new[] { 0d, 0d, 0d })] + [InlineData("100, 200, 300", 800d, 600d, new[] { 100d, 200d, 300d })] + [InlineData("100, 200, 300", 600d, 600d, new[] { 100d, 200d, 300d })] + [InlineData("100, 200, 300", 400d, 400d, new[] { 100d, 200d, 100d })] + public void MeasureArrange_AllPixelLength_Correct(string length, double containerLength, + double expectedDesiredLength, IList expectedLengthList) + { + TestRowDefinitionsOnly(length, containerLength, expectedDesiredLength, expectedLengthList); + } + + [Theory] + [InlineData("*,2*,3*", 0d, 0d, new[] { 0d, 0d, 0d })] + [InlineData("*,2*,3*", 600d, 0d, new[] { 100d, 200d, 300d })] + public void MeasureArrange_AllStarLength_Correct(string length, double containerLength, + double expectedDesiredLength, IList expectedLengthList) + { + TestRowDefinitionsOnly(length, containerLength, expectedDesiredLength, expectedLengthList); + } + + [Theory] + [InlineData("100,2*,3*", 0d, 0d, new[] { 0d, 0d, 0d })] + [InlineData("100,2*,3*", 600d, 100d, new[] { 100d, 200d, 300d })] + [InlineData("100,2*,3*", 100d, 100d, new[] { 100d, 0d, 0d })] + [InlineData("100,2*,3*", 50d, 50d, new[] { 50d, 0d, 0d })] + public void MeasureArrange_MixStarPixelLength_Correct(string length, double containerLength, + double expectedDesiredLength, IList expectedLengthList) + { + TestRowDefinitionsOnly(length, containerLength, expectedDesiredLength, expectedLengthList); + } + + [Theory] + [InlineData("100,200,Auto", 0d, 0d, new[] { 0d, 0d, 0d })] + [InlineData("100,200,Auto", 600d, 300d, new[] { 100d, 200d, 0d })] + [InlineData("100,200,Auto", 300d, 300d, new[] { 100d, 200d, 0d })] + [InlineData("100,200,Auto", 200d, 200d, new[] { 100d, 100d, 0d })] + [InlineData("100,200,Auto", 100d, 100d, new[] { 100d, 0d, 0d })] + [InlineData("100,200,Auto", 50d, 50d, new[] { 50d, 0d, 0d })] + public void MeasureArrange_MixAutoPixelLength_Correct(string length, double containerLength, + double expectedDesiredLength, IList expectedLengthList) + { + TestRowDefinitionsOnly(length, containerLength, expectedDesiredLength, expectedLengthList); + } + + [Theory] + [InlineData("*,2*,Auto", 0d, 0d, new[] { 0d, 0d, 0d })] + [InlineData("*,2*,Auto", 600d, 0d, new[] { 200d, 400d, 0d })] + public void MeasureArrange_MixAutoStarLength_Correct(string length, double containerLength, + double expectedDesiredLength, IList expectedLengthList) + { + TestRowDefinitionsOnly(length, containerLength, expectedDesiredLength, expectedLengthList); + } + + [Theory] + [InlineData("*,200,Auto", 0d, 0d, new[] { 0d, 0d, 0d })] + [InlineData("*,200,Auto", 600d, 200d, new[] { 400d, 200d, 0d })] + [InlineData("*,200,Auto", 200d, 200d, new[] { 0d, 200d, 0d })] + [InlineData("*,200,Auto", 100d, 100d, new[] { 0d, 100d, 0d })] + public void MeasureArrange_MixAutoStarPixelLength_Correct(string length, double containerLength, + double expectedDesiredLength, IList expectedLengthList) + { + TestRowDefinitionsOnly(length, containerLength, expectedDesiredLength, expectedLengthList); + } + + [SuppressMessage("ReSharper", "ParameterOnlyUsedForPreconditionCheck.Local")] + private static void TestRowDefinitionsOnly(string length, double containerLength, + double expectedDesiredLength, IList expectedLengthList) + { + // Arrange + var layout = new GridLayout(new RowDefinitions(length)); + + // Measure - Action & Assert + var measure = layout.Measure(containerLength); + Assert.Equal(expectedDesiredLength, measure.DesiredLength); + Assert.Equal(expectedLengthList, measure.LengthList); + + // Arrange - Action & Assert + var arrange = layout.Arrange(containerLength, measure); + Assert.Equal(expectedLengthList, arrange.LengthList); + } + + [Theory] + [InlineData("100, 200, 300", 600d, new[] { 100d, 200d, 300d }, new[] { 100d, 200d, 300d })] + [InlineData("*,2*,3*", 0d, new[] { Inf, Inf, Inf }, new[] { 0d, 0d, 0d })] + [InlineData("100,2*,3*", 100d, new[] { 100d, Inf, Inf }, new[] { 100d, 0d, 0d })] + [InlineData("100,200,Auto", 300d, new[] { 100d, 200d, 0d }, new[] { 100d, 200d, 0d })] + [InlineData("*,2*,Auto", 0d, new[] { Inf, Inf, 0d }, new[] { 0d, 0d, 0d })] + [InlineData("*,200,Auto", 200d, new[] { Inf, 200d, 0d }, new[] { 0d, 200d, 0d })] + public void MeasureArrange_InfiniteMeasure_Correct(string length, double expectedDesiredLength, + IList expectedMeasureList, IList expectedArrangeList) + { + // Arrange + var layout = new GridLayout(new RowDefinitions(length)); + + // Measure - Action & Assert + var measure = layout.Measure(Inf); + Assert.Equal(expectedDesiredLength, measure.DesiredLength); + Assert.Equal(expectedMeasureList, measure.LengthList); + + // Arrange - Action & Assert + var arrange = layout.Arrange(measure.DesiredLength, measure); + Assert.Equal(expectedArrangeList, arrange.LengthList); + } + + [Theory] + [InlineData("Auto,*,*", new[] { 100d, 100d, 100d }, 600d, 300d, new[] { 100d, 250d, 250d })] + public void MeasureArrange_ChildHasSize_Correct(string length, + IList childLengthList, double containerLength, + double expectedDesiredLength, IList expectedLengthList) + { + // Arrange + var lengthList = new ColumnDefinitions(length); + var layout = new GridLayout(lengthList); + layout.AppendMeasureConventions( + Enumerable.Range(0, lengthList.Count).ToDictionary(x => x, x => (x, 1)), + x => childLengthList[x]); + + // Measure - Action & Assert + var measure = layout.Measure(containerLength); + Assert.Equal(expectedDesiredLength, measure.DesiredLength); + Assert.Equal(expectedLengthList, measure.LengthList); + + // Arrange - Action & Assert + var arrange = layout.Arrange(containerLength, measure); + Assert.Equal(expectedLengthList, arrange.LengthList); + } + + [Theory] + [InlineData(Inf, 250d, new[] { 100d, Inf, Inf }, new[] { 100d, 50d, 100d })] + [InlineData(400d, 250d, new[] { 100d, 100d, 200d }, new[] { 100d, 100d, 200d })] + [InlineData(325d, 250d, new[] { 100d, 75d, 150d }, new[] { 100d, 75d, 150d })] + [InlineData(250d, 250d, new[] { 100d, 50d, 100d }, new[] { 100d, 50d, 100d })] + [InlineData(160d, 160d, new[] { 100d, 20d, 40d }, new[] { 100d, 20d, 40d })] + public void MeasureArrange_ChildHasSizeAndHasMultiSpan_Correct( + double containerLength, double expectedDesiredLength, + IList expectedMeasureLengthList, IList expectedArrangeLengthList) + { + var length = "100,*,2*"; + var childLengthList = new[] { 150d, 150d, 150d }; + var spans = new[] { 1, 2, 1 }; + + // Arrange + var lengthList = new ColumnDefinitions(length); + var layout = new GridLayout(lengthList); + layout.AppendMeasureConventions( + Enumerable.Range(0, lengthList.Count).ToDictionary(x => x, x => (x, spans[x])), + x => childLengthList[x]); + + // Measure - Action & Assert + var measure = layout.Measure(containerLength); + Assert.Equal(expectedDesiredLength, measure.DesiredLength); + Assert.Equal(expectedMeasureLengthList, measure.LengthList); + + // Arrange - Action & Assert + var arrange = layout.Arrange( + double.IsInfinity(containerLength) ? measure.DesiredLength : containerLength, + measure); + Assert.Equal(expectedArrangeLengthList, arrange.LengthList); + } + } +} diff --git a/tests/Avalonia.Controls.UnitTests/GridMocks.cs b/tests/Avalonia.Controls.UnitTests/GridMocks.cs new file mode 100644 index 0000000000..23b975207c --- /dev/null +++ b/tests/Avalonia.Controls.UnitTests/GridMocks.cs @@ -0,0 +1,124 @@ +using System; +using System.Diagnostics.CodeAnalysis; +using Xunit; + +namespace Avalonia.Controls.UnitTests +{ + internal static class GridMock + { + /// + /// Create a mock grid to test its row layout. + /// This method contains Arrange (`new Grid()`) and Action (`Measure()`/`Arrange()`). + /// + /// The measure height of this grid. PositiveInfinity by default. + /// The arrange height of this grid. DesiredSize.Height by default. + /// The mock grid that its children bounds will be tested. + internal static Grid New(Size measure = default, Size arrange = default) + { + var grid = new Grid(); + grid.Children.Add(new Border()); + grid.Measure(measure == default ? new Size(double.PositiveInfinity, double.PositiveInfinity) : measure); + grid.Arrange(new Rect(default, arrange == default ? grid.DesiredSize : arrange)); + return grid; + } + + /// + /// Create a mock grid to test its row layout. + /// This method contains Arrange (`new Grid()`) and Action (`Measure()`/`Arrange()`). + /// + /// The row definitions of this mock grid. + /// The measure height of this grid. PositiveInfinity by default. + /// The arrange height of this grid. DesiredSize.Height by default. + /// The mock grid that its children bounds will be tested. + [SuppressMessage("ReSharper", "CompareOfFloatsByEqualityOperator")] + internal static Grid New(RowDefinitions rows, + double measure = default, double arrange = default) + { + var grid = new Grid { RowDefinitions = rows }; + for (var i = 0; i < rows.Count; i++) + { + grid.Children.Add(new Border { [Grid.RowProperty] = i }); + } + + grid.Measure(new Size(double.PositiveInfinity, measure == default ? double.PositiveInfinity : measure)); + if (arrange == default) + { + arrange = measure == default ? grid.DesiredSize.Width : measure; + } + + grid.Arrange(new Rect(0, 0, 0, arrange)); + + return grid; + } + + /// + /// Create a mock grid to test its column layout. + /// This method contains Arrange (`new Grid()`) and Action (`Measure()`/`Arrange()`). + /// + /// The column definitions of this mock grid. + /// The measure width of this grid. PositiveInfinity by default. + /// The arrange width of this grid. DesiredSize.Width by default. + /// The mock grid that its children bounds will be tested. + [SuppressMessage("ReSharper", "CompareOfFloatsByEqualityOperator")] + internal static Grid New(ColumnDefinitions columns, + double measure = default, double arrange = default) + { + var grid = new Grid { ColumnDefinitions = columns }; + for (var i = 0; i < columns.Count; i++) + { + grid.Children.Add(new Border { [Grid.ColumnProperty] = i }); + } + + grid.Measure(new Size(measure == default ? double.PositiveInfinity : measure, double.PositiveInfinity)); + if (arrange == default) + { + arrange = measure == default ? grid.DesiredSize.Width : measure; + } + + grid.Arrange(new Rect(0, 0, arrange, 0)); + + return grid; + } + } + + internal static class GridAssert + { + /// + /// Assert all the children heights. + /// This method will assume that the grid children count equals row count. + /// + /// The children will be fetched through it. + /// Expected row values of every children. + internal static void ChildrenHeight(Grid grid, params double[] rows) + { + if (grid.Children.Count != rows.Length) + { + throw new NotSupportedException(); + } + + for (var i = 0; i < rows.Length; i++) + { + Assert.Equal(rows[i], grid.Children[i].Bounds.Height); + } + } + + /// + /// Assert all the children widths. + /// This method will assume that the grid children count equals row count. + /// + /// The children will be fetched through it. + /// Expected column values of every children. + internal static void ChildrenWidth(Grid grid, params double[] columns) + { + if (grid.Children.Count != columns.Length) + { + throw new NotSupportedException(); + } + + for (var i = 0; i < columns.Length; i++) + { + Assert.Equal(columns[i], grid.Children[i].Bounds.Width); + } + } + } +} diff --git a/tests/Avalonia.Controls.UnitTests/GridTests.cs b/tests/Avalonia.Controls.UnitTests/GridTests.cs index c5aea6501f..4c79b7775b 100644 --- a/tests/Avalonia.Controls.UnitTests/GridTests.cs +++ b/tests/Avalonia.Controls.UnitTests/GridTests.cs @@ -1,7 +1,6 @@ // 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 Avalonia.Controls; using Xunit; namespace Avalonia.Controls.UnitTests @@ -64,5 +63,96 @@ namespace Avalonia.Controls.UnitTests Assert.Equal(new Rect(0, 25, 150, 25), target.Children[1].Bounds); Assert.Equal(new Rect(154, 25, 50, 25), target.Children[2].Bounds); } + + [Fact] + public void Layout_EmptyColumnRow_LayoutLikeANormalPanel() + { + // Arrange & Action + var grid = GridMock.New(arrange: new Size(600, 200)); + + // Assert + GridAssert.ChildrenWidth(grid, 600); + GridAssert.ChildrenHeight(grid, 200); + } + + [Fact] + public void Layout_PixelRowColumn_BoundsCorrect() + { + // Arrange & Action + var rowGrid = GridMock.New(new RowDefinitions("100,200,300")); + var columnGrid = GridMock.New(new ColumnDefinitions("50,100,150")); + + // Assert + GridAssert.ChildrenHeight(rowGrid, 100, 200, 300); + GridAssert.ChildrenWidth(columnGrid, 50, 100, 150); + } + + [Fact] + public void Layout_StarRowColumn_BoundsCorrect() + { + // Arrange & Action + var rowGrid = GridMock.New(new RowDefinitions("1*,2*,3*"), 600); + var columnGrid = GridMock.New(new ColumnDefinitions("*,*,2*"), 600); + + // Assert + GridAssert.ChildrenHeight(rowGrid, 100, 200, 300); + GridAssert.ChildrenWidth(columnGrid, 150, 150, 300); + } + + [Fact] + public void Layout_MixPixelStarRowColumn_BoundsCorrect() + { + // Arrange & Action + var rowGrid = GridMock.New(new RowDefinitions("1*,2*,150"), 600); + var columnGrid = GridMock.New(new ColumnDefinitions("1*,2*,150"), 600); + + // Assert + GridAssert.ChildrenHeight(rowGrid, 150, 300, 150); + GridAssert.ChildrenWidth(columnGrid, 150, 300, 150); + } + + [Fact] + public void Layout_StarRowColumnWithMinLength_BoundsCorrect() + { + // Arrange & Action + var rowGrid = GridMock.New(new RowDefinitions + { + new RowDefinition(1, GridUnitType.Star) { MinHeight = 200 }, + new RowDefinition(1, GridUnitType.Star), + new RowDefinition(1, GridUnitType.Star), + }, 300); + var columnGrid = GridMock.New(new ColumnDefinitions + { + new ColumnDefinition(1, GridUnitType.Star) { MinWidth = 200 }, + new ColumnDefinition(1, GridUnitType.Star), + new ColumnDefinition(1, GridUnitType.Star), + }, 300); + + // Assert + GridAssert.ChildrenHeight(rowGrid, 200, 50, 50); + GridAssert.ChildrenWidth(columnGrid, 200, 50, 50); + } + + [Fact] + public void Layout_StarRowColumnWithMaxLength_BoundsCorrect() + { + // Arrange & Action + var rowGrid = GridMock.New(new RowDefinitions + { + new RowDefinition(1, GridUnitType.Star) { MaxHeight = 200 }, + new RowDefinition(1, GridUnitType.Star), + new RowDefinition(1, GridUnitType.Star), + }, 800); + var columnGrid = GridMock.New(new ColumnDefinitions + { + new ColumnDefinition(1, GridUnitType.Star) { MaxWidth = 200 }, + new ColumnDefinition(1, GridUnitType.Star), + new ColumnDefinition(1, GridUnitType.Star), + }, 800); + + // Assert + GridAssert.ChildrenHeight(rowGrid, 200, 300, 300); + GridAssert.ChildrenWidth(columnGrid, 200, 300, 300); + } } } diff --git a/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Layout.cs b/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Layout.cs index 2c1074aa9a..98e57601a4 100644 --- a/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Layout.cs +++ b/tests/Avalonia.Controls.UnitTests/Presenters/ContentPresenterTests_Layout.cs @@ -233,7 +233,7 @@ namespace Avalonia.Controls.UnitTests.Presenters target.Arrange(new Rect(0, 0, 100, 100)); - Assert.Equal(new Rect(48, 48, 0, 0), content.Bounds); + Assert.Equal(new Rect(32, 32, 0, 0), content.Bounds); } } } \ No newline at end of file diff --git a/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs b/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs index a64e5a8fe0..f320fa6fe8 100644 --- a/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs +++ b/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs @@ -13,8 +13,8 @@ namespace Avalonia.DesignerSupport.Tests { [Theory, InlineData(@"Avalonia.DesignerSupport.TestApp.exe", @"..\..\tests\Avalonia.DesignerSupport.TestApp\MainWindow.xaml"), - InlineData(@"..\..\samples\ControlCatalog.Desktop\bin\$BUILD\ControlCatalog.dll", @"..\..\samples\ControlCatalog\MainWindow.xaml")] - public void DesgignerApiShoudBeOperational(string outputDir, string xamlFile) + InlineData(@"..\..\samples\ControlCatalog.Desktop\bin\$BUILD\net461\ControlCatalog.dll", @"..\..\samples\ControlCatalog\MainWindow.xaml")] + public void DesignerApiShoudBeOperational(string outputDir, string xamlFile) { var xaml = File.ReadAllText(xamlFile); #if DEBUG diff --git a/tests/Avalonia.Interactivity.UnitTests/Properties/AssemblyInfo.cs b/tests/Avalonia.Interactivity.UnitTests/Properties/AssemblyInfo.cs index 49d227c3e9..318b40828e 100644 --- a/tests/Avalonia.Interactivity.UnitTests/Properties/AssemblyInfo.cs +++ b/tests/Avalonia.Interactivity.UnitTests/Properties/AssemblyInfo.cs @@ -4,7 +4,7 @@ using System.Reflection; using Xunit; -[assembly: AssemblyTitle("Avalonia.Interactive.UnitTests")] +[assembly: AssemblyTitle("Avalonia.Interactivity.UnitTests")] // Don't run tests in parallel. [assembly: CollectionBehavior(DisableTestParallelization = true)] \ No newline at end of file diff --git a/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs b/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs index f42e0daf2a..2e0f048e21 100644 --- a/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs +++ b/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs @@ -296,7 +296,7 @@ namespace Avalonia.Markup.UnitTests.Data var data = new Class1 { DoubleValue = 5.6 }; var converter = new Mock(); var target = new BindingExpression( - new ExpressionObserver(data, "DoubleValue"), + new ExpressionObserver(data, "DoubleValue"), typeof(string), converter.Object, converterParameter: "foo"); diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs index ac25b7ccbe..4213a31c39 100644 --- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs +++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs @@ -81,6 +81,21 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml Assert.Equal(21.0, TextBlock.GetFontSize(target)); } + [Fact] + public void Attached_Property_Is_Set_On_Control_Outside_Avalonia_Namspace() + { + // Test for issue #1548 + var xaml = +@" + +"; + + var target = AvaloniaXamlLoader.Parse(xaml); + + Assert.Equal(2, Grid.GetColumn((TestControl)target.Content)); + } + [Fact] public void Attached_Property_With_Namespace_Is_Set() {