diff --git a/.github/PULL_REQUEST_TEMPLATE.md b/.github/PULL_REQUEST_TEMPLATE.md
new file mode 100644
index 0000000000..9a0da4aa9b
--- /dev/null
+++ b/.github/PULL_REQUEST_TEMPLATE.md
@@ -0,0 +1,17 @@
+This template is not intended to be prescriptive, but to help us review pull requests it would be useful if you included as much of the following information as possible:
+
+- What does the pull request do?
+- What is the current behavior?
+- What is the updated/expected behavior with this PR?
+- How was the solution implemented (if it's not obvious)?
+
+Checklist:
+
+- [ ] Added unit tests (if possible)?
+- [ ] Added XML documentation to any related classes?
+- [ ] Consider submitting a PR to https://github.com/AvaloniaUI/Avaloniaui.net with user documentation
+
+If the pull request fixes issue(s) list them like this:
+
+Fixes #123
+Fixes #456
\ No newline at end of file
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..8b7b02de5d
--- /dev/null
+++ b/build/SharedVersion.props
@@ -0,0 +1,13 @@
+
+
+ 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
+
+
\ No newline at end of file
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 3547e33181..6b80225686 100644
--- a/samples/BindingTest/MainWindow.xaml
+++ b/samples/BindingTest/MainWindow.xaml
@@ -1,11 +1,18 @@
+ xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
+ xmlns:vm="clr-namespace:BindingTest.ViewModels"
+ xmlns:local="clr-namespace:BindingTest"
+ Title="AvaloniaUI Bindings Test"
+ Width="800"
+ Height="600">
+
+
+
@@ -40,6 +47,10 @@
+
+
diff --git a/samples/BindingTest/Properties/AssemblyInfo.cs b/samples/BindingTest/Properties/AssemblyInfo.cs
deleted file mode 100644
index 79166d5f29..0000000000
--- a/samples/BindingTest/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 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("BindingTest")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("BindingTest")]
-[assembly: AssemblyCopyright("Copyright © 2015")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("08b3e6b9-1cd5-443c-9f61-6d49d1c5f162")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
index 8a5959e361..24b168c854 100644
--- a/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
+++ b/samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
@@ -1,138 +1,21 @@
-
-
-
+
+
- Debug
- AnyCPU
- {2B888490-D14A-4BCA-AB4B-48676FA93C9B}
- WinExe
- Properties
- ControlCatalog.Desktop
- ControlCatalog.Desktop
- v4.7
- 512
- true
-
- PackageReference
+ Exe
+ net461
-
- AnyCPU
- true
- full
- false
- bin\Debug\
- DEBUG;TRACE
- prompt
- 4
-
-
- x86
- pdbonly
- true
- bin\Release\
- TRACE
- prompt
- 4
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
+
+
+
+
+
-
- {799a7bb5-3c2c-48b6-85a7-406a12c420da}
- Avalonia.DesignerSupport
-
-
- {4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}
- Avalonia.DotNetFrameworkRuntime
-
-
- {bb1f7bb5-6ad4-4776-94d9-c09d0a972658}
- Avalonia.Gtk3
-
-
- {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
-
-
- {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
-
-
- {eb582467-6abb-43a1-b052-e981ba910e3a}
- Avalonia.Visuals
-
-
- {F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}
- Avalonia.Styling
-
-
- {3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}
- Avalonia.Themes.Default
-
-
- {7d2d3083-71dd-4cc9-8907-39a0d86fb322}
- Avalonia.Skia
-
-
- {3E908F67-5543-4879-A1DC-08EACE79B3CD}
- Avalonia.Direct2D1
-
-
- {811A76CF-1CF6-440F-963B-BBE31BD72A82}
- Avalonia.Win32
-
-
- {d0a739b9-3c68-4ba6-a328-41606954b6bd}
- ControlCatalog
-
+
-
+
+
-
\ No newline at end of file
diff --git a/samples/ControlCatalog.Desktop/Properties/AssemblyInfo.cs b/samples/ControlCatalog.Desktop/Properties/AssemblyInfo.cs
deleted file mode 100644
index 78460f60db..0000000000
--- a/samples/ControlCatalog.Desktop/Properties/AssemblyInfo.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-using System.Reflection;
-using System.Runtime.CompilerServices;
-using System.Runtime.InteropServices;
-
-// 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("ControlCatalog.Desktop")]
-[assembly: AssemblyDescription("")]
-[assembly: AssemblyConfiguration("")]
-[assembly: AssemblyCompany("")]
-[assembly: AssemblyProduct("ControlCatalog.Desktop")]
-[assembly: AssemblyCopyright("Copyright © 2016")]
-[assembly: AssemblyTrademark("")]
-[assembly: AssemblyCulture("")]
-
-// Setting ComVisible to false makes the types in this assembly not visible
-// to COM components. If you need to access a type in this assembly from
-// COM, set the ComVisible attribute to true on that type.
-[assembly: ComVisible(false)]
-
-// The following GUID is for the ID of the typelib if this project is exposed to COM
-[assembly: Guid("2b888490-d14a-4bca-ab4b-48676fa93c9b")]
-
-// Version information for an assembly consists of the following four values:
-//
-// Major Version
-// Minor Version
-// Build Number
-// Revision
-//
-// You can specify all the values or you can default the Build and Revision Numbers
-// by using the '*' as shown below:
-// [assembly: AssemblyVersion("1.0.*")]
-[assembly: AssemblyVersion("1.0.0.0")]
-[assembly: AssemblyFileVersion("1.0.0.0")]
diff --git a/samples/ControlCatalog/DecoratedWindow.xaml b/samples/ControlCatalog/DecoratedWindow.xaml
index d3dbad679a..b2f6497caa 100644
--- a/samples/ControlCatalog/DecoratedWindow.xaml
+++ b/samples/ControlCatalog/DecoratedWindow.xaml
@@ -1,7 +1,7 @@
+ Icon="resm:ControlCatalog.Assets.test_icon.ico"
+ xmlns:local="clr-namespace:ControlCatalog" HasSystemDecorations="False">
diff --git a/samples/ControlCatalog/MainView.xaml b/samples/ControlCatalog/MainView.xaml
index 1107d34b3e..377871f658 100644
--- a/samples/ControlCatalog/MainView.xaml
+++ b/samples/ControlCatalog/MainView.xaml
@@ -1,5 +1,5 @@
diff --git a/samples/ControlCatalog/MainWindow.xaml b/samples/ControlCatalog/MainWindow.xaml
index f39beced1a..7029273a84 100644
--- a/samples/ControlCatalog/MainWindow.xaml
+++ b/samples/ControlCatalog/MainWindow.xaml
@@ -1,6 +1,6 @@
+ xmlns:local="clr-namespace:ControlCatalog">
\ No newline at end of file
diff --git a/samples/Directory.Build.props b/samples/Directory.Build.props
new file mode 100644
index 0000000000..7325bab2a3
--- /dev/null
+++ b/samples/Directory.Build.props
@@ -0,0 +1,3 @@
+
+
+
\ No newline at end of file
diff --git a/samples/RenderTest/MainWindow.xaml b/samples/RenderTest/MainWindow.xaml
index 9e9a600161..ce8fd3a43e 100644
--- a/samples/RenderTest/MainWindow.xaml
+++ b/samples/RenderTest/MainWindow.xaml
@@ -1,6 +1,8 @@
+ Title="AvaloniaUI Rendering Test"
+ xmlns:pages="clr-namespace:RenderTest.Pages"
+ Width="800"
+ Height="600">
\ No newline at end of file
diff --git a/src/Windows/Avalonia.Win32/DataObject.cs b/src/Windows/Avalonia.Win32/DataObject.cs
index 34867765e5..13d5f662c2 100644
--- a/src/Windows/Avalonia.Win32/DataObject.cs
+++ b/src/Windows/Avalonia.Win32/DataObject.cs
@@ -7,7 +7,6 @@ using System.Text;
using Avalonia.Input;
using Avalonia.Win32.Interop;
using IDataObject = Avalonia.Input.IDataObject;
-using IOleDataObject = System.Runtime.InteropServices.ComTypes.IDataObject;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
diff --git a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
index aa86ab0f8d..86dcec410b 100644
--- a/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
+++ b/src/Windows/Avalonia.Win32/Interop/UnmanagedMethods.cs
@@ -558,7 +558,18 @@ namespace Avalonia.Win32.Interop
{
DIB_RGB_COLORS = 0, /* color table in RGBs */
DIB_PAL_COLORS /* color table in palette indices */
- };
+ }
+
+ public enum WindowLongParam
+ {
+ GWL_WNDPROC = -4,
+ GWL_HINSTANCE = -6,
+ GWL_HWNDPARENT = -8,
+ GWL_ID = -12,
+ GWL_STYLE = -16,
+ GWL_EXSTYLE = -20,
+ GWL_USERDATA = -21
+ }
[StructLayout(LayoutKind.Sequential)]
public struct RGBQUAD
@@ -615,6 +626,16 @@ namespace Avalonia.Win32.Interop
public uint[] cols;
}
+ [StructLayout(LayoutKind.Sequential)]
+ public struct MINMAXINFO
+ {
+ public POINT ptReserved;
+ public POINT ptMaxSize;
+ public POINT ptMaxPosition;
+ public POINT ptMinTrackSize;
+ public POINT ptMaxTrackSize;
+ }
+
public const int SizeOf_BITMAPINFOHEADER = 40;
[DllImport("user32.dll")]
@@ -849,6 +870,9 @@ namespace Avalonia.Win32.Interop
return SetClassLong64(hWnd, nIndex, dwNewLong);
}
+ [DllImport("user32.dll", EntryPoint = "SetCursor")]
+ internal static extern IntPtr SetCursor(IntPtr hCursor);
+
[DllImport("ole32.dll", PreserveSig = true)]
internal static extern int CoCreateInstance(ref Guid clsid,
IntPtr ignore1, int ignore2, ref Guid iid, [MarshalAs(UnmanagedType.IUnknown), Out] out object pUnkOuter);
@@ -974,7 +998,7 @@ namespace Avalonia.Win32.Interop
public static extern int DragQueryFile(IntPtr hDrop, int iFile, StringBuilder lpszFile, int cch);
[DllImport("ole32.dll", CharSet = CharSet.Auto, ExactSpelling = true, PreserveSig = false)]
- public static extern void DoDragDrop(IDataObject dataObject, IDropSource dropSource, int allowedEffects, int[] finalEffect);
+ public static extern void DoDragDrop(IOleDataObject dataObject, IDropSource dropSource, int allowedEffects, int[] finalEffect);
@@ -1163,27 +1187,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
@@ -1366,13 +1384,13 @@ namespace Avalonia.Win32.Interop
internal interface IDropTarget
{
[PreserveSig]
- UnmanagedMethods.HRESULT DragEnter([MarshalAs(UnmanagedType.Interface)] [In] IDataObject pDataObj, [MarshalAs(UnmanagedType.U4)] [In] int grfKeyState, [MarshalAs(UnmanagedType.U8)] [In] long pt, [In] [Out] ref DropEffect pdwEffect);
+ UnmanagedMethods.HRESULT DragEnter([MarshalAs(UnmanagedType.Interface)] [In] IOleDataObject pDataObj, [MarshalAs(UnmanagedType.U4)] [In] int grfKeyState, [MarshalAs(UnmanagedType.U8)] [In] long pt, [In] [Out] ref DropEffect pdwEffect);
[PreserveSig]
UnmanagedMethods.HRESULT DragOver([MarshalAs(UnmanagedType.U4)] [In] int grfKeyState, [MarshalAs(UnmanagedType.U8)] [In] long pt, [In] [Out] ref DropEffect pdwEffect);
[PreserveSig]
UnmanagedMethods.HRESULT DragLeave();
[PreserveSig]
- UnmanagedMethods.HRESULT Drop([MarshalAs(UnmanagedType.Interface)] [In] IDataObject pDataObj, [MarshalAs(UnmanagedType.U4)] [In] int grfKeyState, [MarshalAs(UnmanagedType.U8)] [In] long pt, [In] [Out] ref DropEffect pdwEffect);
+ UnmanagedMethods.HRESULT Drop([MarshalAs(UnmanagedType.Interface)] [In] IOleDataObject pDataObj, [MarshalAs(UnmanagedType.U4)] [In] int grfKeyState, [MarshalAs(UnmanagedType.U8)] [In] long pt, [In] [Out] ref DropEffect pdwEffect);
}
[ComImport]
@@ -1387,6 +1405,27 @@ namespace Avalonia.Win32.Interop
}
+ [ComImport]
+ [Guid("0000010E-0000-0000-C000-000000000046")]
+ [InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]
+ public interface IOleDataObject
+ {
+ void GetData([In] ref FORMATETC format, out STGMEDIUM medium);
+ void GetDataHere([In] ref FORMATETC format, ref STGMEDIUM medium);
+ [PreserveSig]
+ int QueryGetData([In] ref FORMATETC format);
+ [PreserveSig]
+ int GetCanonicalFormatEtc([In] ref FORMATETC formatIn, out FORMATETC formatOut);
+ void SetData([In] ref FORMATETC formatIn, [In] ref STGMEDIUM medium, [MarshalAs(UnmanagedType.Bool)] bool release);
+ IEnumFORMATETC EnumFormatEtc(DATADIR direction);
+ [PreserveSig]
+ int DAdvise([In] ref FORMATETC pFormatetc, ADVF advf, IAdviseSink adviseSink, out int connection);
+ void DUnadvise(int connection);
+ [PreserveSig]
+ int EnumDAdvise(out IEnumSTATDATA enumAdvise);
+ }
+
+
[StructLayoutAttribute(LayoutKind.Sequential)]
internal struct _DROPFILES
{
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/OleDataObject.cs b/src/Windows/Avalonia.Win32/OleDataObject.cs
index 85d1daadeb..d7b663e7bf 100644
--- a/src/Windows/Avalonia.Win32/OleDataObject.cs
+++ b/src/Windows/Avalonia.Win32/OleDataObject.cs
@@ -8,15 +8,14 @@ using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using Avalonia.Input;
using Avalonia.Win32.Interop;
-using IDataObject = System.Runtime.InteropServices.ComTypes.IDataObject;
namespace Avalonia.Win32
{
class OleDataObject : Avalonia.Input.IDataObject
{
- private IDataObject _wrapped;
+ private IOleDataObject _wrapped;
- public OleDataObject(IDataObject wrapped)
+ public OleDataObject(IOleDataObject wrapped)
{
_wrapped = wrapped;
}
diff --git a/src/Windows/Avalonia.Win32/OleDropTarget.cs b/src/Windows/Avalonia.Win32/OleDropTarget.cs
index 500c03e317..973564a3d1 100644
--- a/src/Windows/Avalonia.Win32/OleDropTarget.cs
+++ b/src/Windows/Avalonia.Win32/OleDropTarget.cs
@@ -3,7 +3,6 @@ using Avalonia.Input.Raw;
using Avalonia.Platform;
using Avalonia.Win32.Interop;
using IDataObject = Avalonia.Input.IDataObject;
-using IOleDataObject = System.Runtime.InteropServices.ComTypes.IDataObject;
namespace Avalonia.Win32
{
diff --git a/src/Windows/Avalonia.Win32/ScreenImpl.cs b/src/Windows/Avalonia.Win32/ScreenImpl.cs
index 113b2811dc..e1df24151d 100644
--- a/src/Windows/Avalonia.Win32/ScreenImpl.cs
+++ b/src/Windows/Avalonia.Win32/ScreenImpl.cs
@@ -2,16 +2,9 @@
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using System;
-using System.Linq;
-using Avalonia.Controls;
using Avalonia.Platform;
-using Avalonia.Utilities;
using static Avalonia.Win32.Interop.UnmanagedMethods;
-#if NETSTANDARD
-using Win32Exception = Avalonia.Win32.NetStandard.AvaloniaWin32Exception;
-#endif
-
namespace Avalonia.Win32
{
public class ScreenImpl : IScreenImpl
diff --git a/src/Windows/Avalonia.Win32/Win32Platform.cs b/src/Windows/Avalonia.Win32/Win32Platform.cs
index 902abaf65b..a5088e794c 100644
--- a/src/Windows/Avalonia.Win32/Win32Platform.cs
+++ b/src/Windows/Avalonia.Win32/Win32Platform.cs
@@ -1,27 +1,23 @@
// 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.Input.Platform;
using System;
using System.Collections.Generic;
-using System.Reactive.Disposables;
+using System.ComponentModel;
using System.Diagnostics.CodeAnalysis;
+using System.IO;
+using System.Reactive.Disposables;
using System.Runtime.InteropServices;
using System.Threading;
+using Avalonia.Controls;
using Avalonia.Controls.Platform;
using Avalonia.Input;
+using Avalonia.Input.Platform;
using Avalonia.Platform;
-using Avalonia.Win32.Input;
-using Avalonia.Win32.Interop;
-using Avalonia.Controls;
using Avalonia.Rendering;
using Avalonia.Threading;
-using System.IO;
-#if NETSTANDARD
-using Win32Exception = Avalonia.Win32.NetStandard.AvaloniaWin32Exception;
-#else
-using System.ComponentModel;
-#endif
+using Avalonia.Win32.Input;
+using Avalonia.Win32.Interop;
namespace Avalonia
{
@@ -86,11 +82,11 @@ namespace Avalonia.Win32
.Bind().ToConstant(s_instance)
.Bind().ToConstant(s_instance);
- if (OleContext.Current != null)
- AvaloniaLocator.CurrentMutable.Bind().ToSingleton();
-
UseDeferredRendering = deferredRendering;
_uiThread = UnmanagedMethods.GetCurrentThreadId();
+
+ if (OleContext.Current != null)
+ AvaloniaLocator.CurrentMutable.Bind().ToSingleton();
}
public bool HasMessages()
diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs
index bb3c4cf6e6..be28b64c5a 100644
--- a/src/Windows/Avalonia.Win32/WindowImpl.cs
+++ b/src/Windows/Avalonia.Win32/WindowImpl.cs
@@ -31,10 +31,14 @@ namespace Avalonia.Win32
private IInputRoot _owner;
private bool _trackingMouse;
private bool _decorated = true;
+ private bool _resizable = true;
private double _scaling = 1;
private WindowState _showWindowState;
private FramebufferManager _framebuffer;
private OleDropTarget _dropTarget;
+ private Size _minSize;
+ private Size _maxSize;
+
#if USE_MANAGED_DRAG
private readonly ManagedWindowResizeDragHelper _managedDrag;
#endif
@@ -77,8 +81,8 @@ namespace Avalonia.Win32
{
get
{
- var style = UnmanagedMethods.GetWindowLong(_hwnd, -16);
- var exStyle = UnmanagedMethods.GetWindowLong(_hwnd, -20);
+ var style = UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE);
+ var exStyle = UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE);
var padding = new UnmanagedMethods.RECT();
if (UnmanagedMethods.AdjustWindowRectEx(ref padding, style, false, exStyle))
@@ -102,6 +106,12 @@ namespace Avalonia.Win32
}
}
+ public void SetMinMaxSize(Size minSize, Size maxSize)
+ {
+ _minSize = minSize;
+ _maxSize = maxSize;
+ }
+
public IScreenImpl Screen
{
get;
@@ -235,7 +245,7 @@ namespace Avalonia.Win32
return;
}
- var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, -16);
+ var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE);
style |= UnmanagedMethods.WindowStyles.WS_OVERLAPPEDWINDOW;
@@ -251,7 +261,7 @@ namespace Avalonia.Win32
Rect newRect;
var oldThickness = BorderThickness;
- UnmanagedMethods.SetWindowLong(_hwnd, -16, (uint)style);
+ UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_STYLE, (uint)style);
if (value)
{
@@ -277,6 +287,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)
@@ -383,8 +408,11 @@ namespace Avalonia.Win32
public void SetCursor(IPlatformHandle cursor)
{
- UnmanagedMethods.SetClassLong(_hwnd, UnmanagedMethods.ClassLongIndex.GCL_HCURSOR,
- cursor?.Handle ?? DefaultCursor);
+ var hCursor = cursor?.Handle ?? DefaultCursor;
+ UnmanagedMethods.SetClassLong(_hwnd, UnmanagedMethods.ClassLongIndex.GCL_HCURSOR, hCursor);
+
+ if (_owner.IsPointerOver)
+ UnmanagedMethods.SetCursor(hCursor);
}
protected virtual IntPtr CreateWindowOverride(ushort atom)
@@ -611,7 +639,26 @@ namespace Avalonia.Win32
case UnmanagedMethods.WindowsMessage.WM_MOVE:
PositionChanged?.Invoke(new Point((short)(ToInt32(lParam) & 0xffff), (short)(ToInt32(lParam) >> 16)));
return IntPtr.Zero;
-
+
+ case UnmanagedMethods.WindowsMessage.WM_GETMINMAXINFO:
+
+ MINMAXINFO mmi = Marshal.PtrToStructure(lParam);
+
+ if (_minSize.Width > 0)
+ mmi.ptMinTrackSize.X = (int)((_minSize.Width * Scaling) + BorderThickness.Left + BorderThickness.Right);
+
+ if (_minSize.Height > 0)
+ mmi.ptMinTrackSize.Y = (int)((_minSize.Height * Scaling) + BorderThickness.Top + BorderThickness.Bottom);
+
+ if (!Double.IsInfinity(_maxSize.Width) && _maxSize.Width > 0)
+ mmi.ptMaxTrackSize.X = (int)((_maxSize.Width * Scaling) + BorderThickness.Left + BorderThickness.Right);
+
+ if (!Double.IsInfinity(_maxSize.Height) && _maxSize.Height > 0)
+ mmi.ptMaxTrackSize.Y = (int)((_maxSize.Height * Scaling) + BorderThickness.Top + BorderThickness.Bottom);
+
+ Marshal.StructureToPtr(mmi, lParam, true);
+ return IntPtr.Zero;
+
case UnmanagedMethods.WindowsMessage.WM_DISPLAYCHANGE:
(Screen as ScreenImpl)?.InvalidateScreensCache();
return IntPtr.Zero;
@@ -798,11 +845,11 @@ namespace Avalonia.Win32
public void ShowTaskbarIcon(bool value)
{
- var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, -20);
-
- style &= ~(UnmanagedMethods.WindowStyles.WS_VISIBLE);
+ var style = (UnmanagedMethods.WindowStyles)UnmanagedMethods.GetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE);
+
+ style &= ~(UnmanagedMethods.WindowStyles.WS_VISIBLE);
- style |= UnmanagedMethods.WindowStyles.WS_EX_TOOLWINDOW;
+ style |= UnmanagedMethods.WindowStyles.WS_EX_TOOLWINDOW;
if (value)
style |= UnmanagedMethods.WindowStyles.WS_EX_APPWINDOW;
else
@@ -813,9 +860,31 @@ namespace Avalonia.Win32
{
//Toggle to make the styles stick
UnmanagedMethods.ShowWindow(_hwnd, ShowWindowCommand.Hide);
- UnmanagedMethods.SetWindowLong(_hwnd, -20, (uint)style);
+ UnmanagedMethods.SetWindowLong(_hwnd, (int)UnmanagedMethods.WindowLongParam.GWL_EXSTYLE, (uint)style);
UnmanagedMethods.ShowWindow(_hwnd, windowPlacement.ShowCmd);
}
}
+
+ public void CanResize(bool value)
+ {
+ if (value == _resizable)
+ {
+ return;
+ }
+
+ 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/src/iOS/Avalonia.iOS/EmbeddableImpl.cs b/src/iOS/Avalonia.iOS/EmbeddableImpl.cs
index 50a3cd9ec0..3d8bafeca9 100644
--- a/src/iOS/Avalonia.iOS/EmbeddableImpl.cs
+++ b/src/iOS/Avalonia.iOS/EmbeddableImpl.cs
@@ -14,6 +14,10 @@ namespace Avalonia.iOS
}
+ public void SetMinMaxSize(Size minSize, Size maxSize)
+ {
+ }
+
public IDisposable ShowDialog()
{
return Disposable.Empty;
diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_AddOwner.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_AddOwner.cs
new file mode 100644
index 0000000000..4e033be3fb
--- /dev/null
+++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_AddOwner.cs
@@ -0,0 +1,52 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+using Xunit;
+
+namespace Avalonia.Base.UnitTests
+{
+ public class AvaloniaObjectTests_AddOwner
+ {
+ [Fact]
+ public void AddOwnered_Property_Retains_Default_Value()
+ {
+ var target = new Class2();
+
+ Assert.Equal("foodefault", target.GetValue(Class2.FooProperty));
+ }
+
+ [Fact]
+ public void AddOwnered_Property_Does_Not_Retain_Validation()
+ {
+ var target = new Class2();
+
+ target.SetValue(Class2.FooProperty, "throw");
+ }
+
+ private class Class1 : AvaloniaObject
+ {
+ public static readonly StyledProperty FooProperty =
+ AvaloniaProperty.Register(
+ "Foo",
+ "foodefault",
+ validate: ValidateFoo);
+
+ private static string ValidateFoo(AvaloniaObject arg1, string arg2)
+ {
+ if (arg2 == "throw")
+ {
+ throw new IndexOutOfRangeException();
+ }
+
+ return arg2;
+ }
+ }
+
+ private class Class2 : AvaloniaObject
+ {
+ public static readonly StyledProperty FooProperty =
+ Class1.FooProperty.AddOwner();
+ }
+ }
+}
diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Attached.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Attached.cs
new file mode 100644
index 0000000000..02600f5e00
--- /dev/null
+++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Attached.cs
@@ -0,0 +1,73 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+using Xunit;
+
+namespace Avalonia.Base.UnitTests
+{
+ public class AvaloniaObjectTests_Attached
+ {
+ [Fact]
+ public void AddOwnered_Property_Retains_Default_Value()
+ {
+ var target = new Class2();
+
+ Assert.Equal("foodefault", target.GetValue(Class2.FooProperty));
+ }
+
+ [Fact]
+ public void AddOwnered_Property_Retains_Validation()
+ {
+ var target = new Class2();
+
+ Assert.Throws(() => target.SetValue(Class2.FooProperty, "throw"));
+ }
+
+ [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(
+ "Foo",
+ "foodefault",
+ validate: ValidateFoo);
+
+ private static string ValidateFoo(AvaloniaObject arg1, string arg2)
+ {
+ if (arg2 == "throw")
+ {
+ throw new IndexOutOfRangeException();
+ }
+
+ return arg2;
+ }
+ }
+
+ private class Class2 : Base
+ {
+ public static readonly AttachedProperty FooProperty =
+ Class1.FooProperty.AddOwner();
+ }
+
+ private class Class3 : Base
+ {
+ }
+ }
+}
diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs
index c75150ca6d..80cd52d529 100644
--- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs
+++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_Binding.cs
@@ -92,14 +92,13 @@ namespace Avalonia.Base.UnitTests
}
[Fact]
- public void Bind_Throws_Exception_For_Unregistered_Property()
+ public void Bind_Does_Not_Throw_Exception_For_Unregistered_Property()
{
Class1 target = new Class1();
- Assert.Throws(() =>
- {
- target.Bind(Class2.BarProperty, Observable.Return("foo"));
- });
+ target.Bind(Class2.BarProperty, Observable.Never().StartWith("foo"));
+
+ Assert.Equal("foo", target.GetValue(Class2.BarProperty));
}
[Fact]
diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_GetValue.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_GetValue.cs
index 98f7289228..740023fd37 100644
--- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_GetValue.cs
+++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_GetValue.cs
@@ -46,11 +46,11 @@ namespace Avalonia.Base.UnitTests
}
[Fact]
- public void GetValue_Throws_Exception_For_Unregistered_Property()
+ public void GetValue_Doesnt_Throw_Exception_For_Unregistered_Property()
{
var target = new Class3();
- Assert.Throws(() => target.GetValue(Class1.FooProperty));
+ Assert.Equal("foodefault", target.GetValue(Class1.FooProperty));
}
private class Class1 : AvaloniaObject
diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_SetValue.cs b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_SetValue.cs
index 1f9c47f8ae..a56cd717b9 100644
--- a/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_SetValue.cs
+++ b/tests/Avalonia.Base.UnitTests/AvaloniaObjectTests_SetValue.cs
@@ -30,6 +30,16 @@ namespace Avalonia.Base.UnitTests
Assert.Equal("newvalue", target.GetValue(Class1.FooProperty));
}
+ [Fact]
+ public void SetValue_Sets_Attached_Value()
+ {
+ Class2 target = new Class2();
+
+ target.SetValue(AttachedOwner.AttachedProperty, "newvalue");
+
+ Assert.Equal("newvalue", target.GetValue(AttachedOwner.AttachedProperty));
+ }
+
[Fact]
public void SetValue_Raises_PropertyChanged()
{
@@ -84,14 +94,27 @@ namespace Avalonia.Base.UnitTests
}
[Fact]
- public void SetValue_Throws_Exception_For_Unregistered_Property()
+ public void SetValue_Allows_Setting_Unregistered_Property()
{
Class1 target = new Class1();
- Assert.Throws(() =>
- {
- target.SetValue(Class2.BarProperty, "invalid");
- });
+ Assert.False(AvaloniaPropertyRegistry.Instance.IsRegistered(target, Class2.BarProperty));
+
+ target.SetValue(Class2.BarProperty, "bar");
+
+ Assert.Equal("bar", target.GetValue(Class2.BarProperty));
+ }
+
+ [Fact]
+ public void SetValue_Allows_Setting_Unregistered_Attached_Property()
+ {
+ Class1 target = new Class1();
+
+ Assert.False(AvaloniaPropertyRegistry.Instance.IsRegistered(target, AttachedOwner.AttachedProperty));
+
+ target.SetValue(AttachedOwner.AttachedProperty, "bar");
+
+ Assert.Equal("bar", target.GetValue(AttachedOwner.AttachedProperty));
}
[Fact]
@@ -189,6 +212,12 @@ namespace Avalonia.Base.UnitTests
}
}
+ private class AttachedOwner
+ {
+ public static readonly AttachedProperty AttachedProperty =
+ AvaloniaProperty.RegisterAttached("Attached");
+ }
+
private class ImplictDouble
{
public ImplictDouble(double value)
diff --git a/tests/Avalonia.Base.UnitTests/AvaloniaPropertyRegistryTests.cs b/tests/Avalonia.Base.UnitTests/AvaloniaPropertyRegistryTests.cs
index da0b0252a3..8b2e500d37 100644
--- a/tests/Avalonia.Base.UnitTests/AvaloniaPropertyRegistryTests.cs
+++ b/tests/Avalonia.Base.UnitTests/AvaloniaPropertyRegistryTests.cs
@@ -4,12 +4,13 @@
using System.Linq;
using System.Reactive.Linq;
using Xunit;
+using Xunit.Abstractions;
namespace Avalonia.Base.UnitTests
{
public class AvaloniaPropertyRegistryTests
{
- public AvaloniaPropertyRegistryTests()
+ public AvaloniaPropertyRegistryTests(ITestOutputHelper s)
{
// Ensure properties are registered.
AvaloniaProperty p;
@@ -25,7 +26,7 @@ namespace Avalonia.Base.UnitTests
.Select(x => x.Name)
.ToArray();
- Assert.Equal(new[] { "Foo", "Baz", "Qux", "Attached" }, names);
+ Assert.Equal(new[] { "Foo", "Baz", "Qux" }, names);
}
[Fact]
@@ -35,61 +36,41 @@ namespace Avalonia.Base.UnitTests
.Select(x => x.Name)
.ToArray();
- Assert.Equal(new[] { "Bar", "Flob", "Fred", "Foo", "Baz", "Qux", "Attached" }, names);
+ Assert.Equal(new[] { "Bar", "Flob", "Fred", "Foo", "Baz", "Qux" }, names);
}
[Fact]
- public void GetAttached_Returns_Registered_Properties_For_Base_Types()
+ public void GetRegisteredAttached_Returns_Registered_Properties()
{
- string[] names = AvaloniaPropertyRegistry.Instance.GetAttached(typeof(AttachedOwner)).Select(x => x.Name).ToArray();
+ string[] names = AvaloniaPropertyRegistry.Instance.GetRegisteredAttached(typeof(Class1))
+ .Select(x => x.Name)
+ .ToArray();
Assert.Equal(new[] { "Attached" }, names);
}
[Fact]
- public void FindRegistered_Finds_Untyped_Property()
+ public void GetRegisteredAttached_Returns_Registered_Properties_For_Base_Types()
{
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class1), "Foo");
+ string[] names = AvaloniaPropertyRegistry.Instance.GetRegisteredAttached(typeof(Class2))
+ .Select(x => x.Name)
+ .ToArray();
- Assert.Equal(Class1.FooProperty, result);
+ Assert.Equal(new[] { "Attached" }, names);
}
[Fact]
- public void FindRegistered_Finds_Typed_Property()
+ public void FindRegistered_Finds_Property()
{
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class1), "Class1.Foo");
+ var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class1), "Foo");
Assert.Equal(Class1.FooProperty, result);
}
[Fact]
- public void FindRegistered_Finds_Typed_Inherited_Property()
- {
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class2), "Class1.Foo");
-
- Assert.Equal(Class2.FooProperty, result);
- }
-
- [Fact]
- public void FindRegistered_Finds_Inherited_Property_With_Derived_Type_Name()
- {
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class2), "Class2.Foo");
-
- Assert.Equal(Class2.FooProperty, result);
- }
-
- [Fact]
- public void FindRegistered_Finds_Attached_Property()
- {
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class2), "AttachedOwner.Attached");
-
- Assert.Equal(AttachedOwner.AttachedProperty, result);
- }
-
- [Fact]
- public void FindRegistered_Doesnt_Finds_Unqualified_Attached_Property()
+ public void FindRegistered_Doesnt_Find_Nonregistered_Property()
{
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class2), "Attached");
+ var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class1), "Bar");
Assert.Null(result);
}
@@ -99,55 +80,34 @@ namespace Avalonia.Base.UnitTests
{
var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(AttachedOwner), "Attached");
- Assert.True(AttachedOwner.AttachedProperty == result);
+ Assert.Same(AttachedOwner.AttachedProperty, result);
}
[Fact]
- public void FindRegistered_Finds_AddOwnered_Untyped_Attached_Property()
+ public void FindRegistered_Finds_AddOwnered_Attached_Property()
{
var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class3), "Attached");
- Assert.True(AttachedOwner.AttachedProperty == result);
+ Assert.Same(AttachedOwner.AttachedProperty, result);
}
[Fact]
- public void FindRegistered_Finds_AddOwnered_Typed_Attached_Property()
+ public void FindRegistered_Doesnt_Find_Non_AddOwnered_Attached_Property()
{
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class3), "Class3.Attached");
-
- Assert.True(AttachedOwner.AttachedProperty == result);
- }
-
- [Fact]
- public void FindRegistered_Finds_AddOwnered_AttachedTyped_Attached_Property()
- {
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class3), "AttachedOwner.Attached");
-
- Assert.True(AttachedOwner.AttachedProperty == result);
- }
-
- [Fact]
- public void FindRegistered_Finds_AddOwnered_BaseTyped_Attached_Property()
- {
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class3), "Class1.Attached");
-
- Assert.True(AttachedOwner.AttachedProperty == result);
- }
-
- [Fact]
- public void FindRegistered_Doesnt_Find_Nonregistered_Property()
- {
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class1), "Bar");
+ var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class2), "Attached");
Assert.Null(result);
}
[Fact]
- public void FindRegistered_Doesnt_Find_Nonregistered_Attached_Property()
+ public void FindRegisteredAttached_Finds_Property()
{
- var result = AvaloniaPropertyRegistry.Instance.FindRegistered(typeof(Class4), "AttachedOwner.Attached");
+ var result = AvaloniaPropertyRegistry.Instance.FindRegisteredAttached(
+ typeof(Class1),
+ typeof(AttachedOwner),
+ "Attached");
- Assert.Null(result);
+ Assert.Equal(AttachedOwner.AttachedProperty, result);
}
private class Class1 : AvaloniaObject
@@ -176,18 +136,18 @@ namespace Avalonia.Base.UnitTests
private class Class3 : Class1
{
- public static readonly StyledProperty AttachedProperty =
+ public static readonly AttachedProperty AttachedProperty =
AttachedOwner.AttachedProperty.AddOwner();
}
- public class Class4 : AvaloniaObject
- {
- }
-
private class AttachedOwner : Class1
{
public static readonly AttachedProperty AttachedProperty =
AvaloniaProperty.RegisterAttached("Attached");
}
+
+ private class AttachedOwner2 : AttachedOwner
+ {
+ }
}
}
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/GridLengthTests.cs b/tests/Avalonia.Controls.UnitTests/GridLengthTests.cs
index 0a811333d4..ab4da0ca7e 100644
--- a/tests/Avalonia.Controls.UnitTests/GridLengthTests.cs
+++ b/tests/Avalonia.Controls.UnitTests/GridLengthTests.cs
@@ -13,7 +13,7 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Parse_Should_Parse_Auto()
{
- var result = GridLength.Parse("Auto", CultureInfo.InvariantCulture);
+ var result = GridLength.Parse("Auto");
Assert.Equal(GridLength.Auto, result);
}
@@ -21,7 +21,7 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Parse_Should_Parse_Auto_Lowercase()
{
- var result = GridLength.Parse("auto", CultureInfo.InvariantCulture);
+ var result = GridLength.Parse("auto");
Assert.Equal(GridLength.Auto, result);
}
@@ -29,7 +29,7 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Parse_Should_Parse_Star()
{
- var result = GridLength.Parse("*", CultureInfo.InvariantCulture);
+ var result = GridLength.Parse("*");
Assert.Equal(new GridLength(1, GridUnitType.Star), result);
}
@@ -37,7 +37,7 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Parse_Should_Parse_Star_Value()
{
- var result = GridLength.Parse("2*", CultureInfo.InvariantCulture);
+ var result = GridLength.Parse("2*");
Assert.Equal(new GridLength(2, GridUnitType.Star), result);
}
@@ -45,7 +45,7 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Parse_Should_Parse_Pixel_Value()
{
- var result = GridLength.Parse("2", CultureInfo.InvariantCulture);
+ var result = GridLength.Parse("2");
Assert.Equal(new GridLength(2, GridUnitType.Pixel), result);
}
@@ -53,13 +53,13 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void Parse_Should_Throw_FormatException_For_Invalid_String()
{
- Assert.Throws(() => GridLength.Parse("2x", CultureInfo.InvariantCulture));
+ Assert.Throws(() => GridLength.Parse("2x"));
}
[Fact]
public void ParseLengths_Accepts_Comma_Separators()
{
- var result = GridLength.ParseLengths("*,Auto,2*,4", CultureInfo.InvariantCulture).ToList();
+ var result = GridLength.ParseLengths("*,Auto,2*,4").ToList();
Assert.Equal(
new[]
@@ -75,7 +75,7 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void ParseLengths_Accepts_Space_Separators()
{
- var result = GridLength.ParseLengths("* Auto 2* 4", CultureInfo.InvariantCulture).ToList();
+ var result = GridLength.ParseLengths("* Auto 2* 4").ToList();
Assert.Equal(
new[]
@@ -91,7 +91,7 @@ namespace Avalonia.Controls.UnitTests
[Fact]
public void ParseLengths_Accepts_Comma_Separators_With_Spaces()
{
- var result = GridLength.ParseLengths("*, Auto, 2* ,4", CultureInfo.InvariantCulture).ToList();
+ var result = GridLength.ParseLengths("*, Auto, 2* ,4").ToList();
Assert.Equal(
new[]
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.DesignerSupport.Tests/DesignerSupportTests.cs b/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs
index a64e5a8fe0..32da700acc 100644
--- a/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs
+++ b/tests/Avalonia.DesignerSupport.Tests/DesignerSupportTests.cs
@@ -11,10 +11,10 @@ namespace Avalonia.DesignerSupport.Tests
{
public class DesignerSupportTests
{
- [Theory,
+ [Theory(Skip = "Skipping for now as failing on AppVeyor"),
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)
+ 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 6eeaa029de..2e0f048e21 100644
--- a/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs
+++ b/tests/Avalonia.Markup.UnitTests/Data/BindingExpressionTests.cs
@@ -58,7 +58,7 @@ namespace Avalonia.Markup.UnitTests.Data
[Fact]
public async Task Should_Convert_Get_String_To_Double()
{
- var data = new Class1 { StringValue = "5.6" };
+ var data = new Class1 { StringValue = $"{5.6}" };
var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double));
var result = await target.Take(1);
@@ -94,12 +94,12 @@ namespace Avalonia.Markup.UnitTests.Data
[Fact]
public void Should_Convert_Set_String_To_Double()
{
- var data = new Class1 { StringValue = (5.6).ToString() };
+ var data = new Class1 { StringValue = $"{5.6}" };
var target = new BindingExpression(new ExpressionObserver(data, "StringValue"), typeof(double));
target.OnNext(6.7);
- Assert.Equal((6.7).ToString(), data.StringValue);
+ Assert.Equal($"{6.7}", data.StringValue);
GC.KeepAlive(data);
}
@@ -111,7 +111,7 @@ namespace Avalonia.Markup.UnitTests.Data
var target = new BindingExpression(new ExpressionObserver(data, "DoubleValue"), typeof(string));
var result = await target.Take(1);
- Assert.Equal((5.6).ToString(), result);
+ Assert.Equal($"{5.6}", result);
GC.KeepAlive(data);
}
@@ -122,7 +122,7 @@ namespace Avalonia.Markup.UnitTests.Data
var data = new Class1 { DoubleValue = 5.6 };
var target = new BindingExpression(new ExpressionObserver(data, "DoubleValue"), typeof(string));
- target.OnNext("6.7");
+ target.OnNext($"{6.7}");
Assert.Equal(6.7, data.DoubleValue);
@@ -318,15 +318,15 @@ namespace Avalonia.Markup.UnitTests.Data
target.Subscribe(x => result.Add(x));
target.OnNext(1.2);
- target.OnNext("3.4");
+ target.OnNext($"{3.4}");
target.OnNext("bar");
Assert.Equal(
new[]
{
- new BindingNotification("5.6"),
- new BindingNotification("1.2"),
- new BindingNotification("3.4"),
+ new BindingNotification($"{5.6}"),
+ new BindingNotification($"{1.2}"),
+ new BindingNotification($"{3.4}"),
new BindingNotification(
new InvalidCastException("'bar' is not a valid number."),
BindingErrorType.Error)
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs
new file mode 100644
index 0000000000..4b0bee00f3
--- /dev/null
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/BindingExtensionTests.cs
@@ -0,0 +1,71 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+using Avalonia.Controls;
+using Avalonia.Controls.Presenters;
+using Avalonia.Controls.Templates;
+using Avalonia.Styling;
+using Avalonia.UnitTests;
+using Xunit;
+
+namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
+{
+ public class BindingExtensionTests
+ {
+
+ [Fact]
+ public void BindingExtension_Binds_To_Source()
+ {
+ using (StyledWindow())
+ {
+ var xaml = @"
+
+
+ foobar
+
+
+
+";
+
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var textBlock = window.FindControl("textBlock");
+
+ window.Show();
+
+ Assert.Equal("foobar", textBlock.Text);
+ }
+ }
+
+ private IDisposable StyledWindow(params (string, string)[] assets)
+ {
+ var services = TestServices.StyledWindow.With(
+ assetLoader: new MockAssetLoader(assets),
+ theme: () => new Styles
+ {
+ WindowStyle(),
+ });
+
+ return UnitTestApplication.Start(services);
+ }
+
+ private Style WindowStyle()
+ {
+ return new Style(x => x.OfType())
+ {
+ Setters =
+ {
+ new Setter(
+ Window.TemplateProperty,
+ new FuncControlTemplate(x =>
+ new ContentPresenter
+ {
+ Name = "PART_ContentPresenter",
+ [!ContentPresenter.ContentProperty] = x[!Window.ContentProperty],
+ }))
+ }
+ };
+ }
+ }
+}
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs
index 862ce2b3c0..8615efd967 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/MarkupExtensions/StaticResourceExtensionTests.cs
@@ -323,7 +323,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
Assert.Equal(0xff506070, brush.Color.ToUint32());
}
- [Fact(Skip = "Not yet supported by Portable.Xaml")]
+ [Fact]
public void StaticResource_Can_Be_Assigned_To_Property_In_ControlTemplate_In_Styles_File()
{
var styleXaml = @"
@@ -361,9 +361,7 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
var border = (Border)button.GetVisualChildren().Single();
var brush = (SolidColorBrush)border.Background;
-
- // To make this work we somehow need to be able to get hold of the parent ambient
- // context from Portable.Xaml. See TODO in StaticResourceExtension.
+
Assert.Equal(0xff506070, brush.Color.ToUint32());
}
}
@@ -417,6 +415,79 @@ namespace Avalonia.Markup.Xaml.UnitTests.MarkupExtensions
}
}
+ [Fact]
+ public void StaticResource_Can_Be_Assigned_To_Binding_Converter_In_DataTemplate()
+ {
+ using (StyledWindow())
+ {
+ var xaml = @"
+
+
+
+
+
+
+
+
+
+";
+
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+
+ window.DataContext = "foo";
+ var presenter = window.FindControl("presenter");
+
+ window.Show();
+
+ var textBlock = (TextBlock)presenter.GetVisualChildren().Single();
+
+ Assert.NotNull(textBlock);
+ Assert.Equal("foobar", textBlock.Text);
+ }
+ }
+
+ [Fact]
+ public void StaticResource_Is_Correctly_Chosen_From_Within_DataTemplate()
+ {
+ // this tests if IAmbientProviders in DataTemplate contexts are in correct order
+ // if they wouldn't be, Purple brush would be bound to
+ using (StyledWindow())
+ {
+ var xaml = @"
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+";
+
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+
+ window.Show();
+
+ var textBlock = window.GetVisualDescendants().OfType().Single();
+
+ Assert.NotNull(textBlock);
+ Assert.Equal("White-bar", textBlock.Text);
+ }
+ }
+
[Fact]
public void Control_Property_Is_Not_Updated_When_Parent_Is_Changed()
{
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/AttachedPropertyOwner.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/AttachedPropertyOwner.cs
new file mode 100644
index 0000000000..aac5b01f96
--- /dev/null
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/AttachedPropertyOwner.cs
@@ -0,0 +1,14 @@
+using System;
+using Avalonia.Controls;
+
+namespace Avalonia.Markup.Xaml.UnitTests.Xaml
+{
+ public class AttachedPropertyOwner
+ {
+ public static readonly AttachedProperty DoubleProperty =
+ AvaloniaProperty.RegisterAttached("Double");
+
+ public static double GetDouble(Control control) => control.GetValue(DoubleProperty);
+ public static void SetDouble(Control control, double value) => control.SetValue(DoubleProperty, value);
+ }
+}
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
index ba68838382..4213a31c39 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BasicTests.cs
@@ -11,6 +11,7 @@ using Avalonia.Media;
using Avalonia.Media.Immutable;
using Avalonia.Styling;
using Avalonia.UnitTests;
+using Portable.Xaml;
using System.Collections;
using System.ComponentModel;
using System.Linq;
@@ -80,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()
{
@@ -125,6 +141,24 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
Assert.Equal("Foo", ToolTip.GetTip(target));
}
+ [Fact]
+ public void NonExistent_Property_Throws()
+ {
+ var xaml =
+ @"";
+
+ Assert.Throws(() => AvaloniaXamlLoader.Parse(xaml));
+ }
+
+ [Fact]
+ public void Non_Attached_Property_With_Attached_Property_Syntax_Throws()
+ {
+ var xaml =
+ @"";
+
+ Assert.Throws(() => AvaloniaXamlLoader.Parse(xaml));
+ }
+
[Fact]
public void ContentControl_ContentTemplate_Is_Functional()
{
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs
index a44d09dee7..568c6482f5 100644
--- a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/BindingTests.cs
@@ -215,5 +215,71 @@ namespace Avalonia.Markup.Xaml.UnitTests.Xaml
Assert.Equal("bar", textBlock.Text);
}
}
+
+ [Fact]
+ public void Binding_To_Namespaced_Attached_Property_Works()
+ {
+ using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
+ {
+ var xaml = @"
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var textBlock = (TextBlock)window.Content;
+
+ window.DataContext = 5.6;
+ window.ApplyTemplate();
+
+ Assert.Equal(5.6, AttachedPropertyOwner.GetDouble(textBlock));
+ }
+ }
+
+ [Fact]
+ public void Binding_To_AddOwnered_Attached_Property_Works()
+ {
+ using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
+ {
+ var xaml = @"
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var testControl = (TestControl)window.Content;
+
+ window.DataContext = 5.6;
+ window.ApplyTemplate();
+
+ Assert.Equal(5.6, testControl.Double);
+ }
+ }
+
+ [Fact]
+ public void Binding_To_Attached_Property_Using_AddOwnered_Type_Works()
+ {
+ using (UnitTestApplication.Start(TestServices.MockWindowingPlatform))
+ {
+ var xaml = @"
+
+
+";
+ var loader = new AvaloniaXamlLoader();
+ var window = (Window)loader.Load(xaml);
+ var textBlock = (TextBlock)window.Content;
+
+ window.DataContext = 5.6;
+ window.ApplyTemplate();
+
+ Assert.Equal(5.6, AttachedPropertyOwner.GetDouble(textBlock));
+ }
+ }
}
}
\ No newline at end of file
diff --git a/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/TestControl.cs b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/TestControl.cs
new file mode 100644
index 0000000000..d0591e5ee6
--- /dev/null
+++ b/tests/Avalonia.Markup.Xaml.UnitTests/Xaml/TestControl.cs
@@ -0,0 +1,17 @@
+using System;
+using Avalonia.Controls;
+
+namespace Avalonia.Markup.Xaml.UnitTests.Xaml
+{
+ public class TestControl : Control
+ {
+ public static readonly StyledProperty DoubleProperty =
+ AttachedPropertyOwner.DoubleProperty.AddOwner();
+
+ public double Double
+ {
+ get => GetValue(DoubleProperty);
+ set => SetValue(DoubleProperty, value);
+ }
+ }
+}
diff --git a/tests/Avalonia.UnitTests/MockAssetLoader.cs b/tests/Avalonia.UnitTests/MockAssetLoader.cs
index 5cff20c6a1..d6b70aee16 100644
--- a/tests/Avalonia.UnitTests/MockAssetLoader.cs
+++ b/tests/Avalonia.UnitTests/MockAssetLoader.cs
@@ -27,6 +27,11 @@ namespace Avalonia.UnitTests
{
return new MemoryStream(Encoding.UTF8.GetBytes(_assets[uri]));
}
+
+ public Tuple OpenAndGetAssembly(Uri uri, Uri baseUri = null)
+ {
+ return Tuple.Create(Open(uri, baseUri), (Assembly)null);
+ }
public void SetDefaultAssembly(Assembly asm)
{
diff --git a/tests/Avalonia.Visuals.UnitTests/CornerRadiusTests.cs b/tests/Avalonia.Visuals.UnitTests/CornerRadiusTests.cs
index bc0bbdc867..56f9907409 100644
--- a/tests/Avalonia.Visuals.UnitTests/CornerRadiusTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/CornerRadiusTests.cs
@@ -11,7 +11,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Parses_Single_Uniform_Radius()
{
- var result = CornerRadius.Parse("3.4", CultureInfo.InvariantCulture);
+ var result = CornerRadius.Parse("3.4");
Assert.Equal(new CornerRadius(3.4), result);
}
@@ -19,7 +19,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Parses_Top_Bottom()
{
- var result = CornerRadius.Parse("1.1,2.2", CultureInfo.InvariantCulture);
+ var result = CornerRadius.Parse("1.1,2.2");
Assert.Equal(new CornerRadius(1.1, 2.2), result);
}
@@ -27,7 +27,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Parses_TopLeft_TopRight_BottomRight_BottomLeft()
{
- var result = CornerRadius.Parse("1.1,2.2,3.3,4.4", CultureInfo.InvariantCulture);
+ var result = CornerRadius.Parse("1.1,2.2,3.3,4.4");
Assert.Equal(new CornerRadius(1.1, 2.2, 3.3, 4.4), result);
}
@@ -35,7 +35,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Accepts_Spaces()
{
- var result = CornerRadius.Parse("1.1 2.2 3.3 4.4", CultureInfo.InvariantCulture);
+ var result = CornerRadius.Parse("1.1 2.2 3.3 4.4");
Assert.Equal(new CornerRadius(1.1, 2.2, 3.3, 4.4), result);
}
diff --git a/tests/Avalonia.Visuals.UnitTests/Media/MatrixTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/MatrixTests.cs
index 4c1e361952..ff1d17164e 100644
--- a/tests/Avalonia.Visuals.UnitTests/Media/MatrixTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/Media/MatrixTests.cs
@@ -8,7 +8,7 @@ namespace Avalonia.Visuals.UnitTests.Media
[Fact]
public void Parse_Parses()
{
- var matrix = Matrix.Parse("1,2,3,-4,5 6", CultureInfo.CurrentCulture);
+ var matrix = Matrix.Parse("1,2,3,-4,5 6");
var expected = new Matrix(1, 2, 3, -4, 5, 6);
Assert.Equal(expected, matrix);
}
diff --git a/tests/Avalonia.Visuals.UnitTests/Media/RectTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/RectTests.cs
index 12070bfed3..cd0c7e1ace 100644
--- a/tests/Avalonia.Visuals.UnitTests/Media/RectTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/Media/RectTests.cs
@@ -8,7 +8,7 @@ namespace Avalonia.Visuals.UnitTests.Media
[Fact]
public void Parse_Parses()
{
- var rect = Rect.Parse("1,2 3,-4", CultureInfo.CurrentCulture);
+ var rect = Rect.Parse("1,2 3,-4");
var expected = new Rect(1, 2, 3, -4);
Assert.Equal(expected, rect);
}
diff --git a/tests/Avalonia.Visuals.UnitTests/RelativePointTests.cs b/tests/Avalonia.Visuals.UnitTests/RelativePointTests.cs
index f4a21fb6b4..b9eecc809f 100644
--- a/tests/Avalonia.Visuals.UnitTests/RelativePointTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/RelativePointTests.cs
@@ -11,7 +11,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Should_Accept_Absolute_Value()
{
- var result = RelativePoint.Parse("4,5", CultureInfo.InvariantCulture);
+ var result = RelativePoint.Parse("4,5");
Assert.Equal(new RelativePoint(4, 5, RelativeUnit.Absolute), result);
}
@@ -19,7 +19,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Should_Accept_Relative_Value()
{
- var result = RelativePoint.Parse("25%, 50%", CultureInfo.InvariantCulture);
+ var result = RelativePoint.Parse("25%, 50%");
Assert.Equal(new RelativePoint(0.25, 0.5, RelativeUnit.Relative), result);
}
diff --git a/tests/Avalonia.Visuals.UnitTests/RelativeRectTests.cs b/tests/Avalonia.Visuals.UnitTests/RelativeRectTests.cs
index 9f25dcd413..68a0df2d9b 100644
--- a/tests/Avalonia.Visuals.UnitTests/RelativeRectTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/RelativeRectTests.cs
@@ -14,7 +14,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Should_Accept_Absolute_Value()
{
- var result = RelativeRect.Parse("4,5,50,60", CultureInfo.InvariantCulture);
+ var result = RelativeRect.Parse("4,5,50,60");
Assert.Equal(new RelativeRect(4, 5, 50, 60, RelativeUnit.Absolute), result, Compare);
}
@@ -22,7 +22,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Should_Accept_Relative_Value()
{
- var result = RelativeRect.Parse("10%, 20%, 40%, 70%", CultureInfo.InvariantCulture);
+ var result = RelativeRect.Parse("10%, 20%, 40%, 70%");
Assert.Equal(new RelativeRect(0.1, 0.2, 0.4, 0.7, RelativeUnit.Relative), result, Compare);
}
@@ -31,7 +31,7 @@ namespace Avalonia.Visuals.UnitTests
public void Parse_Should_Throw_Mixed_Values()
{
Assert.Throws(() =>
- RelativeRect.Parse("10%, 20%, 40, 70%", CultureInfo.InvariantCulture));
+ RelativeRect.Parse("10%, 20%, 40, 70%"));
}
}
}
diff --git a/tests/Avalonia.Visuals.UnitTests/ThicknessTests.cs b/tests/Avalonia.Visuals.UnitTests/ThicknessTests.cs
index 03bf395d1e..ac4c6bc781 100644
--- a/tests/Avalonia.Visuals.UnitTests/ThicknessTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/ThicknessTests.cs
@@ -11,7 +11,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Parses_Single_Uniform_Size()
{
- var result = Thickness.Parse("1.2", CultureInfo.InvariantCulture);
+ var result = Thickness.Parse("1.2");
Assert.Equal(new Thickness(1.2), result);
}
@@ -19,7 +19,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Parses_Horizontal_Vertical()
{
- var result = Thickness.Parse("1.2,3.4", CultureInfo.InvariantCulture);
+ var result = Thickness.Parse("1.2,3.4");
Assert.Equal(new Thickness(1.2, 3.4), result);
}
@@ -27,7 +27,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Parses_Left_Top_Right_Bottom()
{
- var result = Thickness.Parse("1.2, 3.4, 5, 6", CultureInfo.InvariantCulture);
+ var result = Thickness.Parse("1.2, 3.4, 5, 6");
Assert.Equal(new Thickness(1.2, 3.4, 5, 6), result);
}
@@ -35,7 +35,7 @@ namespace Avalonia.Visuals.UnitTests
[Fact]
public void Parse_Accepts_Spaces()
{
- var result = Thickness.Parse("1.2 3.4 5 6", CultureInfo.InvariantCulture);
+ var result = Thickness.Parse("1.2 3.4 5 6");
Assert.Equal(new Thickness(1.2, 3.4, 5, 6), result);
}