1
0
Эх сурвалжийг харах

Merge remote-tracking branch 'remotes/origin/master' into portablexaml

# Conflicts:
#	samples/BindingTest/packages.config
Andrey Kunchev 8 жил өмнө
parent
commit
1fffdf6ecf
100 өөрчлөгдсөн 1646 нэмэгдсэн , 1358 устгасан
  1. 6 0
      .travis.yml
  2. 162 11
      Avalonia.sln
  3. 1 1
      Avalonia.v3.ncrunchsolution
  4. 11 4
      appveyor.yml
  5. 66 58
      build.cake
  6. 5 0
      build/JetBrains.Annotations.props
  7. 5 0
      build/JetBrains.dotMemoryUnit.props
  8. 5 0
      build/Magick.NET-Q16-AnyCPU.props
  9. 9 0
      build/Markup.props
  10. 5 0
      build/Microsoft.CSharp.props
  11. 5 0
      build/Microsoft.Reactive.Testing.props
  12. 5 0
      build/Moq.props
  13. 6 0
      build/NetCore.props
  14. 11 0
      build/Rx.props
  15. 5 0
      build/Serilog.Sinks.Trace.props
  16. 5 0
      build/Serilog.props
  17. 8 0
      build/SharpDX.props
  18. 5 0
      build/SkiaSharp.Desktop.props
  19. 5 0
      build/SkiaSharp.props
  20. 5 0
      build/Splat.props
  21. 5 0
      build/Sprache.props
  22. 29 0
      build/UnitTests.NetCore.targets
  23. 13 0
      build/XUnit.props
  24. 27 0
      build/readme.md
  25. 1 1
      docs/guidelines/build.md
  26. 57 26
      packages.cake
  27. 1 1
      readme.md
  28. 2 2
      samples/BindingTest/App.config
  29. 7 21
      samples/BindingTest/BindingTest.csproj
  30. 0 8
      samples/BindingTest/packages.config
  31. 2 8
      samples/ControlCatalog.Android/ControlCatalog.Android.csproj
  32. 0 4
      samples/ControlCatalog.Android/GettingStarted.Xamarin
  33. 7 2
      samples/ControlCatalog.Android/Resources/Resource.Designer.cs
  34. 8 0
      samples/ControlCatalog.Desktop/App.config
  35. 5 17
      samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
  36. 0 4
      samples/ControlCatalog.Desktop/packages.config
  37. 14 0
      samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
  38. 29 0
      samples/ControlCatalog.NetCore/Program.cs
  39. 1 0
      samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj
  40. 19 80
      samples/ControlCatalog/ControlCatalog.csproj
  41. 0 4
      samples/ControlCatalog/packages.config
  42. 2 2
      samples/RenderTest/MainWindow.xaml.cs
  43. 6 41
      samples/RenderTest/RenderTest.csproj
  44. 0 11
      samples/RenderTest/packages.config
  45. 8 0
      samples/VirtualizationTest/App.config
  46. 6 29
      samples/VirtualizationTest/VirtualizationTest.csproj
  47. 0 7
      samples/VirtualizationTest/packages.config
  48. 6 0
      samples/interop/Direct3DInteropSample/App.paml
  49. 13 0
      samples/interop/Direct3DInteropSample/App.paml.cs
  50. 34 0
      samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
  51. 264 0
      samples/interop/Direct3DInteropSample/MainWindow.cs
  52. 14 0
      samples/interop/Direct3DInteropSample/MainWindow.paml
  53. 45 0
      samples/interop/Direct3DInteropSample/MainWindowViewModel.cs
  54. 47 0
      samples/interop/Direct3DInteropSample/MiniCube.fx
  55. 17 0
      samples/interop/Direct3DInteropSample/Program.cs
  56. 1 7
      samples/interop/GtkInteropDemo/GtkInteropDemo.csproj
  57. 12 0
      samples/interop/WindowsInteropTest/App.config
  58. 1 7
      samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
  59. 1 0
      src/Android/Avalonia.Android/AndroidPlatform.cs
  60. 6 21
      src/Android/Avalonia.Android/Avalonia.Android.csproj
  61. 5 2
      src/Android/Avalonia.Android/Resources/Resource.Designer.cs
  62. 0 19
      src/Android/Avalonia.Android/packages.config
  63. 6 36
      src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
  64. 1 0
      src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs
  65. 0 25
      src/Android/Avalonia.AndroidTestApplication/packages.config
  66. 5 62
      src/Avalonia.Animation/Avalonia.Animation.csproj
  67. 0 8
      src/Avalonia.Animation/packages.config
  68. 5 51
      src/Avalonia.Base/Avalonia.Base.csproj
  69. 0 41
      src/Avalonia.Base/AvaloniaDisposable.cs
  70. 7 4
      src/Avalonia.Base/AvaloniaObject.cs
  71. 1 1
      src/Avalonia.Base/AvaloniaProperty.cs
  72. 5 0
      src/Avalonia.Base/IPriorityValueOwner.cs
  73. 2 0
      src/Avalonia.Base/PriorityBindingEntry.cs
  74. 11 7
      src/Avalonia.Base/PriorityLevel.cs
  75. 12 8
      src/Avalonia.Base/PriorityValue.cs
  76. 1 0
      src/Avalonia.Base/Properties/AssemblyInfo.cs
  77. 37 18
      src/Avalonia.Base/Threading/Dispatcher.cs
  78. 39 0
      src/Avalonia.Base/Threading/IDispatcher.cs
  79. 10 3
      src/Avalonia.Base/Threading/JobRunner.cs
  80. 162 75
      src/Avalonia.Base/Utilities/TypeUtilities.cs
  81. 0 9
      src/Avalonia.Base/packages.config
  82. 12 248
      src/Avalonia.Controls/Avalonia.Controls.csproj
  83. 1 1
      src/Avalonia.Controls/Button.cs
  84. 35 1
      src/Avalonia.Controls/Control.cs
  85. 13 14
      src/Avalonia.Controls/Presenters/TextPresenter.cs
  86. 8 9
      src/Avalonia.Controls/Primitives/AccessText.cs
  87. 1 31
      src/Avalonia.Controls/Primitives/PopupRoot.cs
  88. 1 1
      src/Avalonia.Controls/Primitives/Thumb.cs
  89. 9 12
      src/Avalonia.Controls/TextBlock.cs
  90. 1 1
      src/Avalonia.Controls/TextBox.cs
  91. 25 15
      src/Avalonia.Controls/TopLevel.cs
  92. 0 1
      src/Avalonia.Controls/Utils/UndoRedoHelper.cs
  93. 31 13
      src/Avalonia.Controls/Window.cs
  94. 88 3
      src/Avalonia.Controls/WindowBase.cs
  95. 0 9
      src/Avalonia.Controls/packages.config
  96. 16 95
      src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj
  97. 0 8
      src/Avalonia.DesignerSupport/packages.config
  98. 20 122
      src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj
  99. 5 5
      src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs
  100. 26 23
      src/Avalonia.Diagnostics/ViewModels/TreeNode.cs

+ 6 - 0
.travis.yml

@@ -2,8 +2,14 @@ language: csharp
 os:
   - linux
   - osx
+dist: trusty
+env:
+  global:
+    - DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
+    - DOTNET_CLI_TELEMETRY_OPTOUT=1
 mono:
   - latest
+dotnet: 1.0.1
 script:
   - ./build.sh --target "Travis" --platform "Mono" --configuration "Release"
 notifications:

+ 162 - 11
Avalonia.sln

@@ -1,6 +1,6 @@
 Microsoft Visual Studio Solution File, Format Version 12.00
-# Visual Studio 14
-VisualStudioVersion = 14.0.25420.1
+# Visual Studio 15
+VisualStudioVersion = 15.0.26228.4
 MinimumVisualStudioVersion = 10.0.40219.1
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Base", "src\Avalonia.Base\Avalonia.Base.csproj", "{B09B78D8-9B26-48B0-9149-D64A2F120F3F}"
 EndProject
@@ -15,9 +15,6 @@ EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Direct2D1", "src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj", "{3E908F67-5543-4879-A1DC-08EACE79B3CD}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Designer", "src\Windows\Avalonia.Designer\Avalonia.Designer.csproj", "{EC42600F-049B-43FF-AED1-8314D61B2749}"
-	ProjectSection(ProjectDependencies) = postProject
-		{2B888490-D14A-4BCA-AB4B-48676FA93C9B} = {2B888490-D14A-4BCA-AB4B-48676FA93C9B}
-	EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Input", "src\Avalonia.Input\Avalonia.Input.csproj", "{62024B2D-53EB-4638-B26B-85EEAA54866E}"
 EndProject
@@ -85,9 +82,6 @@ EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "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}"
-	ProjectSection(ProjectDependencies) = postProject
-		{B61B66A3-B82D-4875-8001-89D3394FE0C9} = {B61B66A3-B82D-4875-8001-89D3394FE0C9}
-	EndProjectSection
 EndProject
 Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "RenderHelpers", "src\Shared\RenderHelpers\RenderHelpers.shproj", "{3C4C0CB4-0C0F-4450-A37B-148C84FF905F}"
 EndProject
@@ -126,9 +120,6 @@ EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog", "samples\ControlCatalog\ControlCatalog.csproj", "{D0A739B9-3C68-4BA6-A328-41606954B6BD}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Desktop", "samples\ControlCatalog.Desktop\ControlCatalog.Desktop.csproj", "{2B888490-D14A-4BCA-AB4B-48676FA93C9B}"
-	ProjectSection(ProjectDependencies) = postProject
-		{BB1F7BB5-6AD4-4776-94D9-C09D0A972658} = {BB1F7BB5-6AD4-4776-94D9-C09D0A972658}
-	EndProjectSection
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.iOS", "samples\ControlCatalog.iOS\ControlCatalog.iOS.csproj", "{57E0455D-D565-44BB-B069-EE1AA20F8337}"
 EndProject
@@ -165,6 +156,41 @@ EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Gtk3", "src\Gtk\Avalonia.Gtk3\Avalonia.Gtk3.csproj", "{BB1F7BB5-6AD4-4776-94D9-C09D0A972658}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Portable.Xaml-pcl259", "src\Markup\Portable.Xaml\src\Portable.Xaml\Portable.Xaml-pcl259.csproj", "{179484EC-DB00-451A-AD2D-2E2AB20DE519}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.NetCore", "samples\ControlCatalog.NetCore\ControlCatalog.NetCore.csproj", "{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Build", "Build", "{74487168-7D91-487E-BF93-055F2251461E}"
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Props", "Props", "{F3AC8BC1-27F5-4255-9AFC-04ABFD11683A}"
+	ProjectSection(SolutionItems) = preProject
+		build\JetBrains.Annotations.props = build\JetBrains.Annotations.props
+		build\JetBrains.dotMemoryUnit.props = build\JetBrains.dotMemoryUnit.props
+		build\Magick.NET-Q16-AnyCPU.props = build\Magick.NET-Q16-AnyCPU.props
+		build\Markup.props = build\Markup.props
+		build\Microsoft.CSharp.props = build\Microsoft.CSharp.props
+		build\Microsoft.Reactive.Testing.props = build\Microsoft.Reactive.Testing.props
+		build\Moq.props = build\Moq.props
+		build\NetCore.props = build\NetCore.props
+		build\Rx.props = build\Rx.props
+		build\Serilog.props = build\Serilog.props
+		build\Serilog.Sinks.Trace.props = build\Serilog.Sinks.Trace.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
+		build\XUnit.props = build\XUnit.props
+	EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{4D6FAF79-58B4-482F-9122-0668C346364C}"
+	ProjectSection(SolutionItems) = preProject
+		build\UnitTests.NetCore.targets = build\UnitTests.NetCore.targets
+	EndProjectSection
+EndProject
+Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Linux", "Linux", "{86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.LinuxFramebuffer", "src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj", "{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Direct3DInteropSample", "samples\interop\Direct3DInteropSample\Direct3DInteropSample.csproj", "{638580B0-7910-40EF-B674-DCB34DA308CD}"
 EndProject
 Global
 	GlobalSection(SharedMSBuildProjectFiles) = preSolution
@@ -3044,6 +3070,126 @@ Global
 		{179484EC-DB00-451A-AD2D-2E2AB20DE519}.Release|Mono.Build.0 = Release|Any CPU
 		{179484EC-DB00-451A-AD2D-2E2AB20DE519}.Release|x86.ActiveCfg = Release|Any CPU
 		{179484EC-DB00-451A-AD2D-2E2AB20DE519}.Release|x86.Build.0 = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|Mono.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|Mono.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|Mono.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|Mono.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|x86.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.AppStore|x86.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|Mono.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|Mono.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Debug|x86.Build.0 = Debug|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|Any CPU.Build.0 = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|iPhone.Build.0 = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|Mono.ActiveCfg = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|Mono.Build.0 = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|x86.ActiveCfg = Release|Any CPU
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}.Release|x86.Build.0 = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|Mono.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|Mono.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|Mono.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|Mono.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|x86.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.AppStore|x86.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Mono.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|Mono.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Debug|x86.Build.0 = Debug|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Any CPU.Build.0 = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|iPhone.Build.0 = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Mono.ActiveCfg = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|Mono.Build.0 = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|x86.ActiveCfg = Release|Any CPU
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}.Release|x86.Build.0 = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|Mono.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|Mono.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|Mono.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|Mono.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|x86.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.AppStore|x86.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Mono.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|Mono.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Debug|x86.Build.0 = Debug|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Any CPU.Build.0 = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|iPhone.Build.0 = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Mono.ActiveCfg = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|Mono.Build.0 = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|x86.ActiveCfg = Release|Any CPU
+		{638580B0-7910-40EF-B674-DCB34DA308CD}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -3100,5 +3246,10 @@ Global
 		{7D2D3083-71DD-4CC9-8907-39A0D86FB322} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
 		{BB1F7BB5-6AD4-4776-94D9-C09D0A972658} = {B9894058-278A-46B5-B6ED-AD613FCC03B3}
 		{179484EC-DB00-451A-AD2D-2E2AB20DE519} = {8B6A8209-894F-4BA1-B880-965FD453982C}
+		{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3} = {9B9E3891-2366-4253-A952-D08BCEB71098}
+		{F3AC8BC1-27F5-4255-9AFC-04ABFD11683A} = {74487168-7D91-487E-BF93-055F2251461E}
+		{4D6FAF79-58B4-482F-9122-0668C346364C} = {74487168-7D91-487E-BF93-055F2251461E}
+		{854568D5-13D1-4B4F-B50D-534DC7EFD3C9} = {86C53C40-57AA-45B8-AD42-FAE0EFDF0F2B}
+		{638580B0-7910-40EF-B674-DCB34DA308CD} = {A0CC0258-D18C-4AB3-854F-7101680FC3F9}
 	EndGlobalSection
 EndGlobal

+ 1 - 1
Avalonia.v3.ncrunchsolution

@@ -3,7 +3,7 @@
     <AdditionalFilesToIncludeForSolution>
       <Value>tests\TestFiles\**.*</Value>
     </AdditionalFilesToIncludeForSolution>
-    <AllowParallelTestExecution>False</AllowParallelTestExecution>
+    <AllowParallelTestExecution>True</AllowParallelTestExecution>
     <ProjectConfigStoragePathRelativeToSolutionDir>.ncrunch</ProjectConfigStoragePathRelativeToSolutionDir>
     <SolutionConfigured>True</SolutionConfigured>
   </Settings>

+ 11 - 4
appveyor.yml

@@ -1,26 +1,32 @@
-os: Visual Studio 2015
+os: Visual Studio 2017
 platform:
 - Any CPU
+skip_branch_with_pr: true
 configuration:
 - Release
 environment:
+  DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
+  DOTNET_CLI_TELEMETRY_OPTOUT: 1
   NUGET_API_KEY:
     secure: Xv89dlP2MSBZKhl1nrWSxqcDgCXB0HRhOd4SWQ+jRJ7QoLxQel5mLTipXM++J3G5
   NUGET_API_URL: https://www.nuget.org/api/v2/package
   MYGET_API_KEY:
     secure: OtVfyN3ErqQrDTnWH2HDfJDlCiu/i4/X4wFmK3ZXXP7HmCiXYPSbTjMPwwdOxRaK
   MYGET_API_URL: https://www.myget.org/F/avalonia-ci/api/v2/package
+init:
+- ps: (New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/appveyor/ci/master/scripts/xamarin-vs2017-151-fixed.targets', "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Microsoft.Common.Targets\ImportAfter\Xamarin.Common.targets")
 install:
   - if not exist gtk-sharp-2.12.26.msi appveyor DownloadFile http://download.xamarin.com/GTKforWindows/Windows/gtk-sharp-2.12.26.msi
-  - msiexec /i gtk-sharp-2.12.26.msi /qn /norestart
+  - if not exist dotnet-1.0.1.exe appveyor DownloadFile https://go.microsoft.com/fwlink/?linkid=843448 -FileName "dotnet-1.0.1.exe"
+  - ps: Start-Process -FilePath "msiexec" -ArgumentList "/i gtk-sharp-2.12.26.msi /quiet /qn /norestart" -Wait
+  - ps: Start-Process -FilePath "dotnet-1.0.1.exe" -ArgumentList "/quiet" -Wait
   - cmd: set PATH=%programfiles(x86)%\GtkSharp\2.12\bin\;%PATH%
 before_build:
 - git submodule update --init
 build_script:
 - ps: .\build.ps1 -Target "AppVeyor" -Platform "$env:platform" -Configuration "$env:configuration"
 after_build:
-- .\packages\JetBrains.dotMemoryUnit.2.1.20150828.125449\tools\dotMemoryUnit.exe -targetExecutable="%xunit20%\xunit.console.x86.exe" -returnTargetExitCode  --"tests\Avalonia.LeakTests\bin\Release\Avalonia.LeakTests.dll"
-
+- tools\JetBrains.dotMemoryUnit\tools\dotMemoryUnit.exe -targetExecutable="%xunit20%\xunit.console.x86.exe" -returnTargetExitCode  --"tests\Avalonia.LeakTests\bin\Release\Avalonia.LeakTests.dll"
 - "SET PATH=C:\\Python34;C:\\Python34\\Scripts;%PATH%"
 - pip install codecov
 - codecov -f "./artifacts/coverage.xml"
@@ -31,3 +37,4 @@ artifacts:
   - path: artifacts\zip\*.zip
 cache:
   - gtk-sharp-2.12.26.msi
+  - dotnet-1.0.1.exe

+ 66 - 58
build.cake

@@ -4,7 +4,8 @@
 
 #addin "nuget:?package=Polly&version=4.2.0"
 #addin "nuget:?package=NuGet.Core&version=2.12.0"
-
+#tool "nuget:https://dotnet.myget.org/F/nuget-build/?package=NuGet.CommandLine&version=4.3.0-preview1-3980&prerelease"
+#tool "nuget:?package=JetBrains.dotMemoryUnit&version=2.1.20150828.125449"
 ///////////////////////////////////////////////////////////////////////////////
 // TOOLS
 ///////////////////////////////////////////////////////////////////////////////
@@ -96,46 +97,10 @@ Task("Clean")
     CleanDirectory(parameters.TestsRoot);
 });
 
-Task("Prepare-XBuild-Solution")
-    .Does(() =>
-{
-    var blacklistedProjects = new[]
-    {
-        "Avalonia.Win32.NetStandard",
-        "Avalonia.DotNetCoreRuntime",
-        "Avalonia.Skia.Desktop.NetStandard",
-        "Avalonia.Gtk3"
-    };
-    var blacklistedGuids = System.IO.File.ReadAllLines(parameters.MSBuildSolution)
-        .Where(l=>l.StartsWith("Project") && blacklistedProjects.Any(p=>l.Contains(p)))
-        .Select(l => l.Split(',').Select(part => part.Trim()).FirstOrDefault(part => part.StartsWith("\"{")))
-        .Where(g=>g!=null)
-        .Select(l=>l.Trim(new[]{'"', '}', '{'}).ToLower()).ToArray();
-
-    Console.WriteLine("Blacklisted guids are: " + string.Join(",", blacklistedGuids));
-    var removeUntilEndProject = false;
-
-    System.IO.File.WriteAllLines(parameters.XBuildSolution, System.IO.File.ReadAllLines(parameters.MSBuildSolution)
-        .Where(l => 
-        {
-            if(removeUntilEndProject)
-            {
-                if(l.StartsWith("EndProject"))
-                    removeUntilEndProject = false;
-                return false;
-            }
-            
-            var blacklist = blacklistedGuids.Any(g => l.ToLower().Contains(g));
-            if(blacklist && l.StartsWith("Project"))
-                removeUntilEndProject = true;
-            
-            return !blacklist;
-        }));
-});
 
 Task("Restore-NuGet-Packages")
     .IsDependentOn("Clean")
-    .IsDependentOn("Prepare-XBuild-Solution")
+    .WithCriteria(parameters.IsRunningOnWindows)
     .Does(() =>
 {
     var maxRetryCount = 5;
@@ -153,21 +118,23 @@ Task("Restore-NuGet-Packages")
                 toolTimeout+=0.5;
             }})
         .Execute(()=> {
-            if(parameters.IsRunningOnWindows)
-            {
                 NuGetRestore(parameters.MSBuildSolution, new NuGetRestoreSettings {
+                    ToolPath = "./tools/NuGet.CommandLine/tools/NuGet.exe",
                     ToolTimeout = TimeSpan.FromMinutes(toolTimeout)
                 });
-            }
-            else
-            {
-                NuGetRestore(parameters.XBuildSolution, new NuGetRestoreSettings {
-                    ToolTimeout = TimeSpan.FromMinutes(toolTimeout)
-                });
-            }
         });
 });
 
+void DotNetCoreBuild()
+{
+    DotNetCoreRestore("samples\\ControlCatalog.NetCore");
+    DotNetBuild("samples\\ControlCatalog.NetCore");
+}
+
+Task("DotNetCoreBuild")
+    .IsDependentOn("Clean")
+    .Does(() => DotNetCoreBuild());
+
 Task("Build")
     .IsDependentOn("Restore-NuGet-Packages")
     .Does(() =>
@@ -177,27 +144,60 @@ Task("Build")
         MSBuild(parameters.MSBuildSolution, settings => {
             settings.SetConfiguration(parameters.Configuration);
             settings.WithProperty("Platform", "\"" + parameters.Platform + "\"");
+            settings.WithProperty("UseRoslynPathHack", "true");
             settings.SetVerbosity(Verbosity.Minimal);
             settings.WithProperty("Windows", "True");
-            settings.UseToolVersion(MSBuildToolVersion.VS2015);
+            settings.UseToolVersion(MSBuildToolVersion.VS2017);
             settings.SetNodeReuse(false);
         });
     }
     else
     {
-        XBuild(parameters.XBuildSolution, settings => {
-            settings.SetConfiguration(parameters.Configuration);
-            settings.WithProperty("Platform", "\"" + parameters.Platform + "\"");
-            settings.SetVerbosity(Verbosity.Minimal);
-        });
+        DotNetCoreBuild();
     }
 });
 
+void RunCoreTest(string dir, Parameters parameters, bool net461Only)
+{
+    Information("Running tests from " + dir);
+    DotNetCoreRestore(dir);
+    var frameworks = new List<string>(){"netcoreapp1.1"};
+    if(parameters.IsRunningOnWindows)
+        frameworks.Add("net461");
+    foreach(var fw in frameworks)
+    {
+        if(fw != "net461" && net461Only)
+            continue;
+        Information("Running for " + fw);
+        DotNetCoreTest(System.IO.Path.Combine(dir, System.IO.Path.GetFileName(dir)+".csproj"),
+            new DotNetCoreTestSettings{Framework = fw});
+    }
+}
+
+
+Task("Run-Net-Core-Unit-Tests")
+    .IsDependentOn("Clean")
+    .Does(() => {
+        RunCoreTest("./tests/Avalonia.Base.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Controls.UnitTests", parameters, true);
+        RunCoreTest("./tests/Avalonia.Input.UnitTests", parameters, true);
+        RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", parameters, true);
+        RunCoreTest("./tests/Avalonia.Layout.UnitTests", parameters, true);
+        //RunCoreTest("./tests/Avalonia.Markup.UnitTests", parameters, true);
+        //RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", parameters, true);
+        RunCoreTest("./tests/Avalonia.Styling.UnitTests", parameters, true);
+        RunCoreTest("./tests/Avalonia.Visuals.UnitTests", parameters, true);
+    });
+
 Task("Run-Unit-Tests")
+    .IsDependentOn("Run-Net-Core-Unit-Tests")
     .IsDependentOn("Build")
     .WithCriteria(() => !parameters.SkipTests)
     .Does(() =>
 {
+    if(!parameters.IsRunningOnWindows)
+       return;
+
     var unitTests = GetDirectories("./tests/Avalonia.*.UnitTests")
         .Select(dir => System.IO.Path.GetFileName(dir.FullPath))
         .Where(name => parameters.IsRunningOnWindows ? true : !(name.IndexOf("Direct2D", StringComparison.OrdinalIgnoreCase) >= 0))
@@ -236,7 +236,11 @@ Task("Run-Unit-Tests")
     {
         CopyDirectory(test.GetDirectory(), parameters.TestsRoot);
     }
-
+    
+    CopyFile(System.IO.Path.Combine(packages.NugetPackagesDir, "SkiaSharp", packages.SkiaSharpVersion,
+        "runtimes", "win7-x86", "native", "libSkiaSharp.dll"),
+        System.IO.Path.Combine(parameters.TestsRoot.ToString(), "libSkiaSharp.dll"));
+    
     var testsInDirectoryToRun = new List<FilePath>();
     if(parameters.IsRunningOnWindows)
     {
@@ -363,16 +367,20 @@ Task("Publish-NuGet")
 Task("Package")
   .IsDependentOn("Create-NuGet-Packages");
 
-Task("Default")
-  .IsDependentOn("Package");
-
+Task("Default").Does(() =>
+{
+    if(parameters.IsRunningOnWindows)
+        RunTarget("Package");
+    else
+        RunTarget("Run-Net-Core-Unit-Tests");
+});
 Task("AppVeyor")
   .IsDependentOn("Zip-Files")
   .IsDependentOn("Publish-MyGet")
   .IsDependentOn("Publish-NuGet");
 
 Task("Travis")
-  .IsDependentOn("Run-Unit-Tests");
+  .IsDependentOn("Run-Net-Core-Unit-Tests");
 
 ///////////////////////////////////////////////////////////////////////////////
 // EXECUTE

+ 5 - 0
build/JetBrains.Annotations.props

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

+ 5 - 0
build/JetBrains.dotMemoryUnit.props

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

+ 5 - 0
build/Magick.NET-Q16-AnyCPU.props

@@ -0,0 +1,5 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.0.0.0101" />
+  </ItemGroup>
+</Project>

+ 9 - 0
build/Markup.props

@@ -0,0 +1,9 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <PackageReference Include="System.ComponentModel.Annotations" Version="4.3.0" />
+    <PackageReference Include="System.Globalization" Version="4.3.0" />
+    <PackageReference Include="System.Linq" Version="4.3.0" />
+    <PackageReference Include="System.Runtime" Version="4.3.0" />
+    <PackageReference Include="System.Text.RegularExpressions" Version="4.3.0" />
+  </ItemGroup>
+</Project>

+ 5 - 0
build/Microsoft.CSharp.props

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

+ 5 - 0
build/Microsoft.Reactive.Testing.props

@@ -0,0 +1,5 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <PackageReference Include="Microsoft.Reactive.Testing" Version="3.0.0" />
+  </ItemGroup>
+</Project>

+ 5 - 0
build/Moq.props

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

+ 6 - 0
build/NetCore.props

@@ -0,0 +1,6 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <PackageReference Include="System.Threading.ThreadPool" Version="4.3.0" />
+    <PackageReference Include="Microsoft.Extensions.DependencyModel" Version="1.1.0" />
+  </ItemGroup>
+</Project>

+ 11 - 0
build/Rx.props

@@ -0,0 +1,11 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <PackageReference Include="System.Reactive" Version="3.0.0" />
+    <PackageReference Include="System.Reactive.Core" Version="3.0.0" />
+    <PackageReference Include="System.Reactive.Interfaces" Version="3.0.0" />
+    <PackageReference Include="System.Reactive.Linq" Version="3.0.0" />
+    <PackageReference Include="System.Reactive.PlatformServices" Version="3.0.0" />
+    <PackageReference Condition="'$(TargetFramework)' == 'net45'" Include="System.Reactive.Windows.Threading" Version="3.0.0" />
+    <PackageReference Condition="'$(TargetFramework)' == 'net461'" Include="System.Reactive.Windows.Threading" Version="3.0.0" />
+  </ItemGroup>
+</Project>

+ 5 - 0
build/Serilog.Sinks.Trace.props

@@ -0,0 +1,5 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+     <PackageReference Include="Serilog.Sinks.Trace" Version="2.1.0" />
+  </ItemGroup>
+</Project>

+ 5 - 0
build/Serilog.props

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

+ 8 - 0
build/SharpDX.props

@@ -0,0 +1,8 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <PackageReference Include="SharpDX" Version="3.1.1" />
+    <PackageReference Include="SharpDX.Direct2D1" Version="3.1.1" />
+    <PackageReference Include="SharpDX.Direct3D11" Version="3.1.1" />
+    <PackageReference Include="SharpDX.DXGI" Version="3.1.1" />
+  </ItemGroup>
+</Project>

+ 5 - 0
build/SkiaSharp.Desktop.props

@@ -0,0 +1,5 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <PackageReference Include="Avalonia.Skia.Linux.Natives" Version="1.56.1.3" />
+  </ItemGroup>
+</Project>

+ 5 - 0
build/SkiaSharp.props

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

+ 5 - 0
build/Splat.props

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

+ 5 - 0
build/Sprache.props

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

+ 29 - 0
build/UnitTests.NetCore.targets

@@ -0,0 +1,29 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+    <GenerateRuntimeConfigurationFiles>true</GenerateRuntimeConfigurationFiles>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <CodeAnalysisRuleSet>MinimumRecommendedRules.ruleset</CodeAnalysisRuleSet>
+  </PropertyGroup>
+  <ItemGroup>
+    <PackageReference Include="System.Threading.Thread" Version="4.3.0" />
+  </ItemGroup>
+  <Import Condition="'$(TargetFramework)' == 'net461'" Project="$(MSBuildThisFileDirectory)..\src\Shared\nuget.workaround.targets" />
+</Project>

+ 13 - 0
build/XUnit.props

@@ -0,0 +1,13 @@
+<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <ItemGroup>
+    <PackageReference Include="xunit" Version="2.2.0" />
+    <PackageReference Include="xunit.abstractions" Version="2.0.1" />
+    <PackageReference Include="xunit.assert" Version="2.2.0" />
+    <PackageReference Include="xunit.core" Version="2.2.0" />
+    <PackageReference Include="xunit.extensibility.core" Version="2.2.0" />
+    <PackageReference Include="xunit.extensibility.execution" Version="2.2.0" />
+    <PackageReference Include="xunit.runner.console" Version="2.2.0" />
+    <PackageReference Condition="'$(TargetFramework)' == 'net461'" Include="xunit.runner.visualstudio" Version="2.2.0" />
+    <PackageReference Condition="'$(TargetFramework)' == 'netcoreapp1.1'" Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+  </ItemGroup>
+</Project>

+ 27 - 0
build/readme.md

@@ -0,0 +1,27 @@
+### MSBuild Props
+
+```XML
+<Import Project="..\..\build\JetBrains.Annotations.props" />
+<Import Project="..\..\build\JetBrains.dotMemoryUnit.props" />
+<Import Project="..\..\build\Magick.NET-Q16-AnyCPU.props" />
+<Import Project="..\..\build\Markup.props" />
+<Import Project="..\..\build\Microsoft.CSharp.props" />
+<Import Project="..\..\build\Microsoft.Reactive.Testing.props" />
+<Import Project="..\..\build\Moq.props" />
+<Import Project="..\..\build\NetCore.props" />
+<Import Project="..\..\build\Rx.props" />
+<Import Project="..\..\build\Serilog.props" />
+<Import Project="..\..\build\Serilog.Sinks.Trace.props" />
+<Import Project="..\..\build\SharpDX.props" />
+<Import Project="..\..\build\SkiaSharp.Desktop.props" />
+<Import Project="..\..\build\SkiaSharp.props" />
+<Import Project="..\..\build\Splat.props" />
+<Import Project="..\..\build\Sprache.props" />
+<Import Project="..\..\build\XUnit.props" />
+```
+
+### MSBuild Targets
+
+```XML
+<Import Project="..\..\build\UnitTests.NetCore.targets" />
+```

+ 1 - 1
docs/guidelines/build.md

@@ -2,7 +2,7 @@
 
 ## Windows
 
-Avalonia requires at least Visual Studio 2015 to build on Windows.
+Avalonia requires at least Visual Studio 2017 to build on Windows.
 
 ### Install GTK Sharp
 

+ 57 - 26
packages.cake

@@ -1,9 +1,12 @@
+using System.Xml.Linq;
+
 public class Packages
 {
     public List<NuGetPackSettings> NuspecNuGetSettings { get; private set; }
     public FilePath[] NugetPackages { get; private set; }
     public FilePath[] BinFiles { get; private set; }
-
+    public string NugetPackagesDir {get; private set;}
+    public string SkiaSharpVersion {get; private set; }
     public Packages(ICakeContext context, Parameters parameters)
     {
         // NUGET NUSPECS
@@ -20,24 +23,30 @@ public class Packages
             path => path.Replace(System.IO.Path.DirectorySeparatorChar, System.IO.Path.AltDirectorySeparatorChar).ToUpperInvariant());
 
         // Key: Package Id
-        // Value is Tuple where Item1: Package Version, Item2: The packages.config file path.
+        // Value is Tuple where Item1: Package Version, Item2: The *.csproj/*.props file path.
         var packageVersions = new Dictionary<string, IList<Tuple<string,string>>>();
 
-        System.IO.Directory.EnumerateFiles(((DirectoryPath)context.Directory("./src")).FullPath, "packages.config", SearchOption.AllDirectories).ToList().ForEach(fileName =>
+        System.IO.Directory.EnumerateFiles(((DirectoryPath)context.Directory("./build")).FullPath,
+            "*.props", SearchOption.AllDirectories).ToList().ForEach(fileName =>
         {
             if (!ignoredSubModulesPaths.Any(i => normalizePath(fileName).Contains(normalizePath(i))))
             {
-                var file = new PackageReferenceFile(fileName);
-                foreach (PackageReference packageReference in file.GetPackageReferences())
+                var xdoc = XDocument.Load(fileName);
+                foreach (var reference in xdoc.Descendants().Where(x => x.Name.LocalName == "PackageReference"))
                 {
+                    var name = reference.Attribute("Include").Value;
+                    var versionAttribute = reference.Attribute("Version");
+                    var version = versionAttribute != null 
+                        ? versionAttribute.Value 
+                        : reference.Elements().First(x=>x.Name.LocalName == "Version").Value;
                     IList<Tuple<string, string>> versions;
-                    packageVersions.TryGetValue(packageReference.Id, out versions);
+                    packageVersions.TryGetValue(name, out versions);
                     if (versions == null)
                     {
                         versions = new List<Tuple<string, string>>();
-                        packageVersions[packageReference.Id] = versions;
+                        packageVersions[name] = versions;
                     }
-                    versions.Add(Tuple.Create(packageReference.Version.ToString(), fileName));
+                    versions.Add(Tuple.Create(version, fileName));
                 }
             }
         });
@@ -65,7 +74,7 @@ public class Packages
         var SplatVersion = packageVersions["Splat"].FirstOrDefault().Item1;
         var SpracheVersion = packageVersions["Sprache"].FirstOrDefault().Item1;
         var SystemReactiveVersion = packageVersions["System.Reactive"].FirstOrDefault().Item1;
-        var SkiaSharpVersion = packageVersions["SkiaSharp"].FirstOrDefault().Item1;
+        SkiaSharpVersion = packageVersions["SkiaSharp"].FirstOrDefault().Item1;
         var SharpDXVersion = packageVersions["SharpDX"].FirstOrDefault().Item1;
         var SharpDXDirect2D1Version = packageVersions["SharpDX.Direct2D1"].FirstOrDefault().Item1;
         var SharpDXDirect3D11Version = packageVersions["SharpDX.Direct3D11"].FirstOrDefault().Item1;
@@ -81,6 +90,11 @@ public class Packages
         context.Information("Package: SharpDX.Direct3D11, version: {0}", SharpDXDirect3D11Version);
         context.Information("Package: SharpDX.DXGI, version: {0}", SharpDXDXGIVersion);
 
+        var nugetPackagesDir = System.Environment.GetEnvironmentVariable("NUGET_HOME")
+            ?? System.IO.Path.Combine(System.Environment.GetEnvironmentVariable("USERPROFILE") ?? System.Environment.GetEnvironmentVariable("HOME"), ".nuget");
+        
+        NugetPackagesDir = System.IO.Path.Combine(nugetPackagesDir, "packages");
+        
         var SetNuGetNuspecCommonProperties = new Action<NuGetPackSettings> ((nuspec) => {
             nuspec.Version = parameters.Version;
             nuspec.Authors = new [] { "Avalonia Team" };
@@ -129,12 +143,12 @@ public class Packages
         };
 
         var coreLibrariesFiles = coreLibraries.Select((lib) => {
-            return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/" + lib[1] + lib[2]);
+            return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard1.1/" + lib[1] + lib[2]);
         }).ToList();
 
         var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
             return new NuSpecContent { 
-                Source = file.FullPath, Target = "lib/portable-windows8+net45" 
+                Source = file.FullPath, Target = "lib/netstandard1.1" 
             };
         });
 
@@ -161,7 +175,7 @@ public class Packages
         var netCoreRuntimePlatformExtensions = new [] {".xml", ".dll"};
         var netCoreRuntimePlatform = netCoreRuntimePlatformExtensions.Select(libSuffix => {
             return new NuSpecContent {
-                Source = ((FilePath)context.File("./src/Avalonia.DotNetCoreRuntime/bin/" + parameters.DirSuffix + "/Avalonia.DotNetCoreRuntime" + libSuffix)).FullPath, 
+                Source = ((FilePath)context.File("./src/Avalonia.DotNetCoreRuntime/bin/" + parameters.DirSuffix + "/netcoreapp1.0/Avalonia.DotNetCoreRuntime" + libSuffix)).FullPath, 
                 Target = "lib/netcoreapp1.0" 
             };
         });
@@ -180,12 +194,12 @@ public class Packages
                     new NuSpecDependency() { Id = "Splat", Version = SplatVersion },
                     new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion },
                     new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion },
-                    new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp1.0", Version = "4.3.0" },
                     //.NET Core
+                    new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp1.0", Version = "4.3.0" },
+                    new NuSpecDependency() { Id = "Microsoft.Extensions.DependencyModel", TargetFramework = "netcoreapp1.0", Version = "1.1.0" },
                     new NuSpecDependency() { Id = "NETStandard.Library", TargetFramework = "netcoreapp1.0", Version = "1.6.0" },
-                    new NuSpecDependency() { Id = "Microsoft.NETCore.Portable.Compatibility", TargetFramework = "netcoreapp1.0", Version = "1.0.1" },
-                    new NuSpecDependency() { Id = "Splat", TargetFramework = "netcoreapp1.0", Version = "2.0.0" },
-                    new NuSpecDependency() { Id = "Serilog", TargetFramework = "netcoreapp1.0", Version = "2.3.0" },
+                    new NuSpecDependency() { Id = "Splat", TargetFramework = "netcoreapp1.0", Version = SplatVersion },
+                    new NuSpecDependency() { Id = "Serilog", TargetFramework = "netcoreapp1.0", Version = SerilogVersion },
                     new NuSpecDependency() { Id = "Sprache", TargetFramework = "netcoreapp1.0", Version = SpracheVersion },
                     new NuSpecDependency() { Id = "System.Reactive", TargetFramework = "netcoreapp1.0", Version = SystemReactiveVersion }
                 },
@@ -208,9 +222,9 @@ public class Packages
                 },
                 Files = new []
                 {
-                    new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/portable-windows8+net45" }
+                    new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/netstandard1.1" }
                 },
-                BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix),
+                BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix + "/netstandard1.1"),
                 OutputDirectory = parameters.NugetRoot
             }
         };
@@ -324,7 +338,7 @@ public class Packages
                 Files = new []
                 {
                     new NuSpecContent { Source = "Avalonia.Win32/bin/" + parameters.DirSuffix + "/Avalonia.Win32.dll", Target = "lib/net45" },
-                    new NuSpecContent { Source = "Avalonia.Win32.NetStandard/bin/" + parameters.DirSuffix + "/Avalonia.Win32.dll", Target = "lib/netstandard1.1" }
+                    new NuSpecContent { Source = "Avalonia.Win32.NetStandard/bin/" + parameters.DirSuffix + "/netstandard1.1/Avalonia.Win32.dll", Target = "lib/netstandard1.1" }
                 },
                 BasePath = context.Directory("./src/Windows"),
                 OutputDirectory = parameters.NugetRoot
@@ -381,7 +395,7 @@ public class Packages
                 {
                     new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard1.1" }
                 },
-                BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix),
+                BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard1.1"),
                 OutputDirectory = parameters.NugetRoot
             },
             ///////////////////////////////////////////////////////////////////////////////
@@ -411,16 +425,15 @@ public class Packages
                 {
                     new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
                     new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion },
-                    //.NET Core
-                    new NuSpecDependency() { Id = "Avalonia", TargetFramework = "netcoreapp1.0", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "SkiaSharp", TargetFramework = "netcoreapp1.0", Version = SkiaSharpVersion },
-                    new NuSpecDependency() { Id = "NETStandard.Library", TargetFramework = "netcoreapp1.0", Version = "1.6.0" },
-                    new NuSpecDependency() { Id = "Microsoft.NETCore.Portable.Compatibility", TargetFramework = "netcoreapp1.0", Version = "1.0.1" }
+                    //netstandard1.3
+                    new NuSpecDependency() { Id = "Avalonia", TargetFramework = "netstandard1.3", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "SkiaSharp", TargetFramework = "netstandard1.3", Version = SkiaSharpVersion },
+                    new NuSpecDependency() { Id = "NETStandard.Library", TargetFramework = "netstandard1.3", Version = "1.6.0" }
                 },
                 Files = new []
                 {
                     new NuSpecContent { Source = "Avalonia.Skia.Desktop/bin/" + parameters.DirSuffixSkia + "/Avalonia.Skia.Desktop.dll", Target = "lib/net45" },
-                    new NuSpecContent { Source = "Avalonia.Skia.Desktop.NetStandard/bin/" + parameters.DirSuffix + "/Avalonia.Skia.Desktop.dll", Target = "lib/netcoreapp1.0" }
+                    new NuSpecContent { Source = "Avalonia.Skia.Desktop.NetStandard/bin/" + parameters.DirSuffix + "/netstandard1.3/Avalonia.Skia.Desktop.dll", Target = "lib/netstandard1.3" }
                 },
                 BasePath = context.Directory("./src/Skia/"),
                 OutputDirectory = parameters.NugetRoot
@@ -445,6 +458,24 @@ public class Packages
                 },
                 BasePath = context.Directory("./"),
                 OutputDirectory = parameters.NugetRoot
+            },
+            ///////////////////////////////////////////////////////////////////////////////
+            // Avalonia.LinuxFramebuffer
+            ///////////////////////////////////////////////////////////////////////////////
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.LinuxFramebuffer",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", Version = parameters.Version }
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.LinuxFramebuffer/bin/" + parameters.DirSuffix + "/netstandard1.3/Avalonia.LinuxFramebuffer.dll", Target = "lib/netstandard1.3" }
+                },
+                BasePath = context.Directory("./src/Linux/"),
+                OutputDirectory = parameters.NugetRoot
             }
         };
 

+ 1 - 1
readme.md

@@ -3,7 +3,7 @@
 
 | Gitter Chat | Windows Build Status | Linux/Mac Build Status | Code Coverage |
 |---|---|---|---|
-| [![Gitter](https://badges.gitter.im/Join Chat.svg)](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [![Build status](https://ci.appveyor.com/api/projects/status/hubk3k0w9idyibfg/branch/master?svg=true)](https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master) | [![Build Status](https://travis-ci.org/AvaloniaUI/Avalonia.svg?branch=master)](https://travis-ci.org/AvaloniaUI/Avalonia) | [![codecov](https://codecov.io/gh/AvaloniaUI/Avalonia/branch/master/graph/badge.svg)](https://codecov.io/gh/AvaloniaUI/Avalonia) |
+| [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/AvaloniaUI/Avalonia?utm_campaign=pr-badge&utm_content=badge&utm_medium=badge&utm_source=badge) | [![Build status](https://ci.appveyor.com/api/projects/status/hubk3k0w9idyibfg/branch/master?svg=true)](https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master) | [![Build Status](https://travis-ci.org/AvaloniaUI/Avalonia.svg?branch=master)](https://travis-ci.org/AvaloniaUI/Avalonia) | [![codecov](https://codecov.io/gh/AvaloniaUI/Avalonia/branch/master/graph/badge.svg)](https://codecov.io/gh/AvaloniaUI/Avalonia) |
 
 A multi-platform .NET UI framework. It can run on Windows, Linux, Mac OS X, iOS and Android.
 

+ 2 - 2
samples/BindingTest/App.config

@@ -7,11 +7,11 @@
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
         <assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-3.0.2.0" newVersion="3.0.2.0" />
+        <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-3.0.2.0" newVersion="3.0.2.0" />
+        <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
       </dependentAssembly>
       <dependentAssembly>
         <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" />

+ 7 - 21
samples/BindingTest/BindingTest.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -13,6 +13,7 @@
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <TargetFrameworkProfile />
+    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -37,18 +38,6 @@
     <StartupObject />
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Serilog.1.5.14\lib\net45\Serilog.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Serilog.FullNetFx, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Serilog.1.5.14\lib\net45\Serilog.FullNetFx.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.ComponentModel.DataAnnotations" />
     <Reference Include="System.Core" />
@@ -96,7 +85,6 @@
     <EmbeddedResource Include="MainWindow.xaml">
       <SubType>Designer</SubType>
     </EmbeddedResource>
-    <None Include="packages.config" />
     <EmbeddedResource Include="TestItemView.xaml" />
   </ItemGroup>
   <ItemGroup>
@@ -182,11 +170,9 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Serilog.props" />
+  <Import Project="..\..\build\Serilog.Sinks.Trace.props" />
+  <Import Project="..\..\build\Splat.props" />
+  <Import Project="..\..\build\Rx.props" />
+  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 8
samples/BindingTest/packages.config

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Serilog" version="1.5.14" targetFramework="net46" />
-  <package id="Splat" version="1.6.2" targetFramework="net46" />
-  <package id="System.Reactive.Core" version="3.0.0" targetFramework="net45" />
-  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="net45" />
-  <package id="System.Reactive.Linq" version="3.0.0" targetFramework="net45" />
-</packages>

+ 2 - 8
samples/ControlCatalog.Android/ControlCatalog.Android.csproj

@@ -73,7 +73,6 @@
     <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
   <ItemGroup>
-    <None Include="GettingStarted.Xamarin" />
     <None Include="Resources\AboutResources.txt" />
     <None Include="Assets\AboutAssets.txt" />
   </ItemGroup>
@@ -157,12 +156,7 @@
       <Name>ControlCatalog</Name>
     </ProjectReference>
   </ItemGroup>
+  <Import Project="..\..\build\Rx.props" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-     Other similar extension points exist, see Microsoft.Common.targets.
-		<Target Name="BeforeBuild">
-		</Target>
-		<Target Name="AfterBuild">
-		</Target>
- -->
+  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 4
samples/ControlCatalog.Android/GettingStarted.Xamarin

@@ -1,4 +0,0 @@
-<GettingStarted>
-	<LocalContent>GS\Android\CS\AndroidApp\GettingStarted.html</LocalContent>
-	<EmbeddedNavigation>false</EmbeddedNavigation>
-</GettingStarted>

+ 7 - 2
samples/ControlCatalog.Android/Resources/Resource.Designer.cs

@@ -28,6 +28,8 @@ namespace ControlCatalog.Android
 		{
 			global::Avalonia.Android.Resource.String.ApplicationName = global::ControlCatalog.Android.Resource.String.ApplicationName;
 			global::Avalonia.Android.Resource.String.Hello = global::ControlCatalog.Android.Resource.String.Hello;
+			global::Avalonia.Android.Resource.String.library_name = global::ControlCatalog.Android.Resource.String.library_name;
+			global::Splat.Resource.String.library_name = global::ControlCatalog.Android.Resource.String.library_name;
 		}
 		
 		public partial class Attribute
@@ -94,11 +96,14 @@ namespace ControlCatalog.Android
 		public partial class String
 		{
 			
+			// aapt resource value: 0x7f040002
+			public const int ApplicationName = 2130968578;
+			
 			// aapt resource value: 0x7f040001
-			public const int ApplicationName = 2130968577;
+			public const int Hello = 2130968577;
 			
 			// aapt resource value: 0x7f040000
-			public const int Hello = 2130968576;
+			public const int library_name = 2130968576;
 			
 			static String()
 			{

+ 8 - 0
samples/ControlCatalog.Desktop/App.config

@@ -9,6 +9,14 @@
         <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" />
         <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
       </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
+      </dependentAssembly>
     </assemblyBinding>
   </runtime>
 </configuration>

+ 5 - 17
samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -13,6 +13,7 @@
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <TargetFrameworkProfile />
+    <RestoreProjectStyle>PackageReference</RestoreProjectStyle>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <PlatformTarget>AnyCPU</PlatformTarget>
@@ -37,14 +38,6 @@
     <StartupObject />
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Serilog.1.5.14\lib\net45\Serilog.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Serilog.FullNetFx, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Serilog.1.5.14\lib\net45\Serilog.FullNetFx.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
     <Reference Include="System.Xml.Linq" />
@@ -57,7 +50,6 @@
   <ItemGroup>
     <Compile Include="Program.cs" />
     <Compile Include="Properties\AssemblyInfo.cs" />
-    <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
     <None Include="App.config" />
@@ -149,11 +141,7 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Serilog.props" />
+  <Import Project="..\..\build\Serilog.Sinks.Trace.props" />
+  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 4
samples/ControlCatalog.Desktop/packages.config

@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Serilog" version="1.5.14" targetFramework="net451" />
-</packages>

+ 14 - 0
samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj

@@ -0,0 +1,14 @@
+<Project Sdk="Microsoft.NET.Sdk">
+
+  <PropertyGroup>
+    <OutputType>Exe</OutputType>
+    <TargetFramework>netcoreapp1.1</TargetFramework>
+  </PropertyGroup>
+
+  <ItemGroup>
+    <ProjectReference Include="..\..\src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj" />
+    <ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
+    <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />
+  </ItemGroup>
+
+</Project>

+ 29 - 0
samples/ControlCatalog.NetCore/Program.cs

@@ -0,0 +1,29 @@
+using System;
+using System.Linq;
+using Avalonia;
+
+namespace ControlCatalog.NetCore
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            if (args.Contains("--fbdev")) AppBuilder.Configure<App>().InitializeWithLinuxFramebuffer(tl =>
+            {
+                tl.Content = new MainView();
+                System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer());
+            });
+            else
+                AppBuilder.Configure<App>()
+                    .UsePlatformDetect()
+                    .Start<MainWindow>();
+        }
+
+        static void ConsoleSilencer()
+        {
+            Console.CursorVisible = false;
+            while (true)
+                Console.ReadKey(true);
+        }
+    }
+}

+ 1 - 0
samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj

@@ -181,4 +181,5 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
+  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 19 - 80
samples/ControlCatalog/ControlCatalog.csproj

@@ -1,20 +1,8 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <MinimumVisualStudioVersion>10.0</MinimumVisualStudioVersion>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{D0A739B9-3C68-4BA6-A328-41606954B6BD}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>ControlCatalog</RootNamespace>
-    <AssemblyName>ControlCatalog</AssemblyName>
-    <DefaultLanguage>en-US</DefaultLanguage>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFramework>netstandard1.1</TargetFramework>
+    <EnableDefaultCompileItems>False</EnableDefaultCompileItems>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
     <DebugSymbols>true</DebugSymbols>
@@ -153,62 +141,20 @@
     </EmbeddedResource>
   </ItemGroup>
   <ItemGroup>
-    <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
-      <Project>{3E53A01A-B331-47F3-B828-4A5717E77A24}</Project>
-      <Name>Avalonia.Markup.Xaml</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
-      <Project>{6417E941-21BC-467B-A771-0DE389353CE6}</Project>
-      <Name>Avalonia.Markup</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj">
-      <Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
-      <Name>Avalonia.Animation</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj">
-      <Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
-      <Name>Avalonia.Base</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj">
-      <Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
-      <Name>Avalonia.Controls</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj">
-      <Project>{7062AE20-5DCC-4442-9645-8195BDECE63E}</Project>
-      <Name>Avalonia.Diagnostics</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.HtmlRenderer\Avalonia.HtmlRenderer.csproj">
-      <Project>{5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}</Project>
-      <Name>Avalonia.HtmlRenderer</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
-      <Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
-      <Name>Avalonia.Input</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
-      <Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
-      <Name>Avalonia.Interactivity</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj">
-      <Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
-      <Name>Avalonia.Layout</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj">
-      <Project>{6417B24E-49C2-4985-8DB2-3AB9D898EC91}</Project>
-      <Name>Avalonia.ReactiveUI</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj">
-      <Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
-      <Name>Avalonia.Visuals</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj">
-      <Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
-      <Name>Avalonia.Styling</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj">
-      <Project>{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}</Project>
-      <Name>Avalonia.Themes.Default</Name>
-    </ProjectReference>
+    <ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />
+    <ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.HtmlRenderer\Avalonia.HtmlRenderer.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj" />
+    <ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="Assets\test_icon.ico" />
@@ -225,12 +171,5 @@
       </SubType>
     </EmbeddedResource>
   </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Serilog.props" />
 </Project>

+ 0 - 4
samples/ControlCatalog/packages.config

@@ -1,4 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Serilog" version="1.5.14" targetFramework="net46" />
-</packages>

+ 2 - 2
samples/RenderTest/MainWindow.xaml.cs

@@ -7,7 +7,6 @@ using Avalonia.Controls;
 using Avalonia.Markup.Xaml;
 using RenderTest.ViewModels;
 using ReactiveUI;
-using Avalonia.Rendering;
 
 namespace RenderTest
 {
@@ -19,7 +18,8 @@ namespace RenderTest
             this.AttachDevTools();
 
             var vm = new MainWindowViewModel();
-            vm.WhenAnyValue(x => x.DrawFps).Subscribe(x => RendererMixin.DrawFpsCounter = x);
+            vm.WhenAnyValue(x => x.DrawDirtyRects).Subscribe(x => Renderer.DrawDirtyRects = x);
+            vm.WhenAnyValue(x => x.DrawFps).Subscribe(x => Renderer.DrawFps = x);
             this.DataContext = vm;
         }
 

+ 6 - 41
samples/RenderTest/RenderTest.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -37,40 +37,8 @@
     <StartupObject />
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Serilog.1.5.14\lib\net45\Serilog.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Serilog.FullNetFx, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Serilog.1.5.14\lib\net45\Serilog.FullNetFx.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
-    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Core.3.0.0\lib\net45\System.Reactive.Core.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Interfaces.3.0.0\lib\net45\System.Reactive.Interfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Linq, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Linq.3.0.0\lib\net45\System.Reactive.Linq.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.PlatformServices, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\net45\System.Reactive.PlatformServices.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Windows.Threading, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Windows.Threading.3.0.0\lib\net45\System.Reactive.Windows.Threading.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
@@ -98,7 +66,6 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="App.config" />
-    <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
     <EmbeddedResource Include="App.xaml">
@@ -212,11 +179,9 @@
     </EmbeddedResource>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Serilog.props" />
+  <Import Project="..\..\build\Serilog.Sinks.Trace.props" />
+  <Import Project="..\..\build\Splat.props" />
+  <Import Project="..\..\build\Rx.props" />
+  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 11
samples/RenderTest/packages.config

@@ -1,11 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Serilog" version="1.5.14" targetFramework="net45" />
-  <package id="Splat" version="1.6.2" targetFramework="net45" />
-  <package id="System.Reactive" version="3.0.0" targetFramework="net45" />
-  <package id="System.Reactive.Core" version="3.0.0" targetFramework="net45" />
-  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="net45" />
-  <package id="System.Reactive.Linq" version="3.0.0" targetFramework="net45" />
-  <package id="System.Reactive.PlatformServices" version="3.0.0" targetFramework="net45" />
-  <package id="System.Reactive.Windows.Threading" version="3.0.0" targetFramework="net45" />
-</packages>

+ 8 - 0
samples/VirtualizationTest/App.config

@@ -9,6 +9,14 @@
         <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" />
         <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
       </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
+      </dependentAssembly>
     </assemblyBinding>
   </runtime>
 </configuration>

+ 6 - 29
samples/VirtualizationTest/VirtualizationTest.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@@ -37,28 +37,8 @@
     <StartupObject />
   </PropertyGroup>
   <ItemGroup>
-    <Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Serilog.1.5.14\lib\net45\Serilog.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Serilog.FullNetFx, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Serilog.1.5.14\lib\net45\Serilog.FullNetFx.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\Splat.1.6.2\lib\Net45\Splat.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
-    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Core.3.0.0\lib\net45\System.Reactive.Core.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Interfaces.3.0.0\lib\net45\System.Reactive.Interfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Data.DataSetExtensions" />
     <Reference Include="Microsoft.CSharp" />
@@ -80,7 +60,6 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="App.config" />
-    <None Include="packages.config" />
   </ItemGroup>
   <ItemGroup>
     <ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj">
@@ -175,11 +154,9 @@
     </EmbeddedResource>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Serilog.props" />
+  <Import Project="..\..\build\Serilog.Sinks.Trace.props" />
+  <Import Project="..\..\build\Splat.props" />
+  <Import Project="..\..\build\Rx.props" />
+  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 0 - 7
samples/VirtualizationTest/packages.config

@@ -1,7 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Serilog" version="1.5.14" targetFramework="net452" />
-  <package id="Splat" version="1.6.2" targetFramework="net452" />
-  <package id="System.Reactive.Core" version="3.0.0" targetFramework="net452" />
-  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="net452" />
-</packages>

+ 6 - 0
samples/interop/Direct3DInteropSample/App.paml

@@ -0,0 +1,6 @@
+<Application xmlns="https://github.com/avaloniaui">
+  <Application.Styles>
+    <StyleInclude Source="resm:Avalonia.Themes.Default.DefaultTheme.xaml?assembly=Avalonia.Themes.Default"/>
+    <StyleInclude Source="resm:Avalonia.Themes.Default.Accents.BaseLight.xaml?assembly=Avalonia.Themes.Default"/>
+  </Application.Styles>
+</Application>

+ 13 - 0
samples/interop/Direct3DInteropSample/App.paml.cs

@@ -0,0 +1,13 @@
+using Avalonia;
+using Avalonia.Markup.Xaml;
+
+namespace Direct3DInteropSample
+{
+    public class App : Application
+    {
+        public override void Initialize()
+        {
+            AvaloniaXamlLoader.Load(this);
+        }
+    }
+}

+ 34 - 0
samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj

@@ -0,0 +1,34 @@
+<Project Sdk="Microsoft.NET.Sdk">
+    <PropertyGroup>
+        <OutputType>Exe</OutputType>
+        <TargetFramework>net461</TargetFramework>
+    </PropertyGroup>
+    <ItemGroup>
+        <PackageReference Include="SharpDX.Mathematics" Version="3.1.1" />
+        <PackageReference Include="SharpDX.D3DCompiler" Version="3.1.1" />
+        <Compile Update="**\*.paml.cs">
+            <DependentUpon>%(Filename)</DependentUpon>
+        </Compile>
+        <EmbeddedResource Include="**\*.paml">
+            <SubType>Designer</SubType>
+        </EmbeddedResource>
+    </ItemGroup>
+    <ItemGroup>
+      <None Remove="MiniCube.fx" />
+    </ItemGroup>
+    <ItemGroup>
+      <EmbeddedResource Include="MiniCube.fx" />
+    </ItemGroup>
+    <ItemGroup>
+        <ProjectReference Include="..\..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" />
+        <ProjectReference Include="..\..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj" />
+        <ProjectReference Include="..\..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
+        <ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" />
+        <ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" />
+    </ItemGroup>
+    <Import Project="..\..\..\build\Serilog.props" />
+    <Import Project="..\..\..\build\Serilog.Sinks.Trace.props" />
+    <Import Project="..\..\..\build\Splat.props" />
+    <Import Project="..\..\..\build\Rx.props" />
+    <Import Project="$(MSBuildThisFileDirectory)..\..\..\src\Shared\nuget.workaround.targets" />
+</Project>

+ 264 - 0
samples/interop/Direct3DInteropSample/MainWindow.cs

@@ -0,0 +1,264 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Avalonia;
+using Avalonia.Controls;
+using Avalonia.Direct2D1.Media;
+using Avalonia.Markup.Xaml;
+using Avalonia.Platform;
+using Avalonia.Rendering;
+using SharpDX;
+using SharpDX.D3DCompiler;
+using SharpDX.Direct2D1;
+using SharpDX.Direct3D;
+using SharpDX.Direct3D11;
+using SharpDX.DXGI;
+using SharpDX.WIC;
+using SharpDX.Mathematics;
+using AlphaMode = SharpDX.Direct2D1.AlphaMode;
+using Buffer = SharpDX.Direct3D11.Buffer;
+using DeviceContext = SharpDX.Direct3D11.DeviceContext;
+using Factory1 = SharpDX.DXGI.Factory1;
+using InputElement = SharpDX.Direct3D11.InputElement;
+using Matrix = SharpDX.Matrix;
+using PixelFormat = SharpDX.Direct2D1.PixelFormat;
+
+namespace Direct3DInteropSample
+{
+    class MainWindow : Window
+    {
+        private SharpDX.Direct3D11.Device _d3dDevice;
+        private SharpDX.DXGI.Device _dxgiDevice;
+        Texture2D backBuffer = null;
+        RenderTargetView renderView = null;
+        Texture2D depthBuffer = null;
+        DepthStencilView depthView = null;
+        private readonly SwapChain _swapChain;
+        private SwapChainDescription _desc;
+        private Matrix _proj = Matrix.Identity;
+        private Matrix _view;
+        private Buffer _contantBuffer;
+        private SharpDX.Direct2D1.Device _d2dDevice;
+        private SharpDX.Direct2D1.DeviceContext _d2dContext;
+        private RenderTarget _d2dRenderTarget;
+        private MainWindowViewModel _model;
+
+        public MainWindow()
+        {
+            _dxgiDevice = AvaloniaLocator.Current.GetService<SharpDX.DXGI.Device>();
+            _d3dDevice = _dxgiDevice.QueryInterface<SharpDX.Direct3D11.Device>();
+            _d2dDevice = AvaloniaLocator.Current.GetService<SharpDX.Direct2D1.Device>();
+            DataContext = _model = new MainWindowViewModel();
+            _desc = new SwapChainDescription()
+            {
+                BufferCount = 1,
+                ModeDescription =
+                   new ModeDescription((int)ClientSize.Width, (int)ClientSize.Height,
+                            new Rational(60, 1), Format.R8G8B8A8_UNorm),
+                IsWindowed = true,
+                OutputHandle = PlatformImpl.Handle.Handle,
+                SampleDescription = new SampleDescription(1, 0),
+                SwapEffect = SwapEffect.Discard,
+                Usage = Usage.RenderTargetOutput
+            };
+
+            _swapChain = new SwapChain(new Factory1(), _d3dDevice, _desc);
+
+            _d2dContext = new SharpDX.Direct2D1.DeviceContext(_d2dDevice, DeviceContextOptions.None)
+            {
+                DotsPerInch = new Size2F(96, 96)
+            };
+
+            CreateMesh();
+            _view = Matrix.LookAtLH(new Vector3(0, 0, -5), new Vector3(0, 0, 0), Vector3.UnitY);
+            this.GetObservable(ClientSizeProperty).Subscribe(Resize);
+            Resize(ClientSize);
+            AvaloniaXamlLoader.Load(this);
+            Background = Avalonia.Media.Brushes.Transparent;
+        }
+
+
+        protected override void HandlePaint(Rect rect)
+        {
+            var viewProj = Matrix.Multiply(_view, _proj);
+            var context = _d3dDevice.ImmediateContext;
+            // Clear views
+            context.ClearDepthStencilView(depthView, DepthStencilClearFlags.Depth, 1.0f, 0);
+            context.ClearRenderTargetView(renderView, Color.White);
+
+            var time = 50;
+            // Update WorldViewProj Matrix
+            var worldViewProj = Matrix.RotationX((float) _model.RotationX) * Matrix.RotationY((float) _model.RotationY) *
+                                Matrix.RotationZ((float) _model.RotationZ)
+                                * Matrix.Scaling((float) _model.Zoom) * viewProj;
+            worldViewProj.Transpose();
+            context.UpdateSubresource(ref worldViewProj, _contantBuffer);
+
+            // Draw the cube
+            context.Draw(36, 0);
+            base.HandlePaint(rect);
+            // Present!
+            _swapChain.Present(0, PresentFlags.None);
+        }
+
+        
+        void CreateMesh()
+        {
+            var device = _d3dDevice;
+            // Compile Vertex and Pixel shaders
+            var vertexShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "VS", "vs_4_0");
+            var vertexShader = new VertexShader(device, vertexShaderByteCode);
+
+            var pixelShaderByteCode = ShaderBytecode.CompileFromFile("MiniCube.fx", "PS", "ps_4_0");
+            var pixelShader = new PixelShader(device, pixelShaderByteCode);
+
+            var signature = ShaderSignature.GetInputSignature(vertexShaderByteCode);
+            // Layout from VertexShader input signature
+            var layout = new InputLayout(device, signature, new[]
+                    {
+                        new InputElement("POSITION", 0, Format.R32G32B32A32_Float, 0, 0),
+                        new InputElement("COLOR", 0, Format.R32G32B32A32_Float, 16, 0)
+                    });
+            
+            // Instantiate Vertex buiffer from vertex data
+            var vertices = Buffer.Create(device, BindFlags.VertexBuffer, new[]
+                                  {
+                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f), // Front
+                                      new Vector4(-1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
+                                      new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
+                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
+                                      new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
+                                      new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 0.0f, 1.0f),
+
+                                      new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f), // BACK
+                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
+                                      new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
+                                      new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
+                                      new Vector4( 1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
+                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 0.0f, 1.0f),
+
+                                      new Vector4(-1.0f, 1.0f, -1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f), // Top
+                                      new Vector4(-1.0f, 1.0f,  1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
+                                      new Vector4( 1.0f, 1.0f,  1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
+                                      new Vector4(-1.0f, 1.0f, -1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
+                                      new Vector4( 1.0f, 1.0f,  1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
+                                      new Vector4( 1.0f, 1.0f, -1.0f,  1.0f), new Vector4(0.0f, 0.0f, 1.0f, 1.0f),
+
+                                      new Vector4(-1.0f,-1.0f, -1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f), // Bottom
+                                      new Vector4( 1.0f,-1.0f,  1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
+                                      new Vector4(-1.0f,-1.0f,  1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
+                                      new Vector4(-1.0f,-1.0f, -1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
+                                      new Vector4( 1.0f,-1.0f, -1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
+                                      new Vector4( 1.0f,-1.0f,  1.0f,  1.0f), new Vector4(1.0f, 1.0f, 0.0f, 1.0f),
+
+                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f), // Left
+                                      new Vector4(-1.0f, -1.0f,  1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
+                                      new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
+                                      new Vector4(-1.0f, -1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
+                                      new Vector4(-1.0f,  1.0f,  1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
+                                      new Vector4(-1.0f,  1.0f, -1.0f, 1.0f), new Vector4(1.0f, 0.0f, 1.0f, 1.0f),
+
+                                      new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f), // Right
+                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
+                                      new Vector4( 1.0f, -1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
+                                      new Vector4( 1.0f, -1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
+                                      new Vector4( 1.0f,  1.0f, -1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
+                                      new Vector4( 1.0f,  1.0f,  1.0f, 1.0f), new Vector4(0.0f, 1.0f, 1.0f, 1.0f),
+                            });
+
+            // Create Constant Buffer
+            _contantBuffer = new Buffer(device, Utilities.SizeOf<Matrix>(), ResourceUsage.Default, BindFlags.ConstantBuffer, CpuAccessFlags.None, ResourceOptionFlags.None, 0);
+
+            var context = _d3dDevice.ImmediateContext;
+
+            // Prepare All the stages
+            context.InputAssembler.InputLayout = layout;
+            context.InputAssembler.PrimitiveTopology = PrimitiveTopology.TriangleList;
+            context.InputAssembler.SetVertexBuffers(0, new VertexBufferBinding(vertices, Utilities.SizeOf<Vector4>() * 2, 0));
+            context.VertexShader.SetConstantBuffer(0, _contantBuffer);
+            context.VertexShader.Set(vertexShader);
+            context.PixelShader.Set(pixelShader);
+        }
+
+        void Resize(Size size)
+        {
+            Utilities.Dispose(ref _d2dRenderTarget);
+            Utilities.Dispose(ref backBuffer);
+            Utilities.Dispose(ref renderView);
+            Utilities.Dispose(ref depthBuffer);
+            Utilities.Dispose(ref depthView);
+            var context = _d3dDevice.ImmediateContext;
+            // Resize the backbuffer
+            _swapChain.ResizeBuffers(_desc.BufferCount, (int)size.Width, (int)size.Height, Format.Unknown, SwapChainFlags.None);
+
+            // Get the backbuffer from the swapchain
+            backBuffer = Texture2D.FromSwapChain<Texture2D>(_swapChain, 0);
+
+            // Renderview on the backbuffer
+            renderView = new RenderTargetView(_d3dDevice, backBuffer);
+
+            // Create the depth buffer
+            depthBuffer = new Texture2D(_d3dDevice, new Texture2DDescription()
+            {
+                Format = Format.D32_Float_S8X24_UInt,
+                ArraySize = 1,
+                MipLevels = 1,
+                Width = (int)size.Width,
+                Height = (int)size.Height,
+                SampleDescription = new SampleDescription(1, 0),
+                Usage = ResourceUsage.Default,
+                BindFlags = BindFlags.DepthStencil,
+                CpuAccessFlags = CpuAccessFlags.None,
+                OptionFlags = ResourceOptionFlags.None
+            });
+
+            // Create the depth buffer view
+            depthView = new DepthStencilView(_d3dDevice, depthBuffer);
+
+            // Setup targets and viewport for rendering
+            context.Rasterizer.SetViewport(new Viewport(0, 0, (int)size.Width, (int)size.Height, 0.0f, 1.0f));
+            context.OutputMerger.SetTargets(depthView, renderView);
+
+            // Setup new projection matrix with correct aspect ratio
+            _proj = Matrix.PerspectiveFovLH((float)Math.PI / 4.0f, (float)(size.Width / size.Height), 0.1f, 100.0f);
+
+            using (var dxgiBackBuffer = _swapChain.GetBackBuffer<Surface>(0))
+            {
+                _d2dRenderTarget = new RenderTarget(AvaloniaLocator.Current.GetService<SharpDX.Direct2D1.Factory>()
+                    , dxgiBackBuffer, new RenderTargetProperties
+                    {
+                        DpiX = 96,
+                        DpiY = 96,
+                        Type = RenderTargetType.Default,
+                        PixelFormat = new PixelFormat(Format.Unknown, AlphaMode.Premultiplied)
+                    });
+            }
+
+        }
+
+        class D3DRenderTarget: IRenderTarget
+        {
+            private readonly MainWindow _window;
+
+            public D3DRenderTarget(MainWindow window)
+            {
+                _window = window;
+            }
+            public void Dispose()
+            {
+                
+            }
+
+            public IDrawingContextImpl CreateDrawingContext(IVisualBrushRenderer visualBrushRenderer)
+            {
+                return new DrawingContextImpl(visualBrushRenderer, _window._d2dRenderTarget,
+                    AvaloniaLocator.Current.GetService<SharpDX.DirectWrite.Factory>());
+            }
+        }
+
+
+        protected override IRenderTarget CreateRenderTarget() => new D3DRenderTarget(this);
+    }
+}

+ 14 - 0
samples/interop/Direct3DInteropSample/MainWindow.paml

@@ -0,0 +1,14 @@
+<Window xmlns="https://github.com/avaloniaui" Background="White" Title="Avalonia Direct3D Demo">
+    <Grid ColumnDefinitions="*,Auto" Margin="20">
+        <StackPanel Grid.Column="1" MinWidth="200">
+            <TextBlock>Rotation X</TextBlock>
+            <Slider Value="{Binding RotationX, Mode=TwoWay}" Maximum="10"/>
+            <TextBlock>Rotation Y</TextBlock>
+            <Slider Value="{Binding RotationY, Mode=TwoWay}" Maximum="10"/>
+            <TextBlock>Rotation Z</TextBlock>
+            <Slider Value="{Binding RotationZ, Mode=TwoWay}" Maximum="10"/>
+            <TextBlock>Zoom</TextBlock>
+            <Slider Value="{Binding Zoom, Mode=TwoWay}" Maximum="3" Minimum="0.5"/>
+        </StackPanel>
+    </Grid>
+</Window>

+ 45 - 0
samples/interop/Direct3DInteropSample/MainWindowViewModel.cs

@@ -0,0 +1,45 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using ReactiveUI;
+
+namespace Direct3DInteropSample
+{
+    public class MainWindowViewModel : ReactiveObject
+    {
+        private double _rotationX;
+
+        public double RotationX
+        {
+            get { return _rotationX; }
+            set { this.RaiseAndSetIfChanged(ref _rotationX, value); }
+        }
+
+        private double _rotationY = 1;
+
+        public double RotationY
+        {
+            get { return _rotationY; }
+            set { this.RaiseAndSetIfChanged(ref _rotationY, value); }
+        }
+
+        private double _rotationZ = 2;
+
+        public double RotationZ
+        {
+            get { return _rotationZ; }
+            set { this.RaiseAndSetIfChanged(ref _rotationZ, value); }
+        }
+
+
+        private double _zoom = 1;
+
+        public double Zoom
+        {
+            get { return _zoom; }
+            set { this.RaiseAndSetIfChanged(ref _zoom, value); }
+        }
+    }
+}

+ 47 - 0
samples/interop/Direct3DInteropSample/MiniCube.fx

@@ -0,0 +1,47 @@
+// Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
+// 
+// Permission is hereby granted, free of charge, to any person obtaining a copy
+// of this software and associated documentation files (the "Software"), to deal
+// in the Software without restriction, including without limitation the rights
+// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+// copies of the Software, and to permit persons to whom the Software is
+// furnished to do so, subject to the following conditions:
+// 
+// The above copyright notice and this permission notice shall be included in
+// all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+// THE SOFTWARE.
+struct VS_IN
+{
+	float4 pos : POSITION;
+	float4 col : COLOR;
+};
+
+struct PS_IN
+{
+	float4 pos : SV_POSITION;
+	float4 col : COLOR;
+};
+
+float4x4 worldViewProj;
+
+PS_IN VS( VS_IN input )
+{
+	PS_IN output = (PS_IN)0;
+	
+	output.pos = mul(input.pos, worldViewProj);
+	output.col = input.col;
+	
+	return output;
+}
+
+float4 PS( PS_IN input ) : SV_Target
+{
+	return input.col;
+}

+ 17 - 0
samples/interop/Direct3DInteropSample/Program.cs

@@ -0,0 +1,17 @@
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using Avalonia;
+
+namespace Direct3DInteropSample
+{
+    class Program
+    {
+        static void Main(string[] args)
+        {
+            AppBuilder.Configure<App>().UseWin32().UseDirect2D1().Start<MainWindow>();
+        }
+    }
+}

+ 1 - 7
samples/interop/GtkInteropDemo/GtkInteropDemo.csproj

@@ -150,11 +150,5 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="$(MSBuildThisFileDirectory)..\..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 12 - 0
samples/interop/WindowsInteropTest/App.config

@@ -3,4 +3,16 @@
     <startup> 
         <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
     </startup>
+  <runtime>
+    <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
+      <dependentAssembly>
+        <assemblyIdentity name="SharpDX" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
+      </dependentAssembly>
+      <dependentAssembly>
+        <assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral" />
+        <bindingRedirect oldVersion="0.0.0.0-3.1.1.0" newVersion="3.1.1.0" />
+      </dependentAssembly>
+    </assemblyBinding>
+  </runtime>
 </configuration>

+ 1 - 7
samples/interop/WindowsInteropTest/WindowsInteropTest.csproj

@@ -180,11 +180,5 @@
     </Page>
   </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="$(MSBuildThisFileDirectory)..\..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 1 - 0
src/Android/Avalonia.Android/AndroidPlatform.cs

@@ -53,6 +53,7 @@ namespace Avalonia.Android
                 .Bind<IKeyboardDevice>().ToSingleton<AndroidKeyboardDevice>()
                 .Bind<IMouseDevice>().ToSingleton<AndroidMouseDevice>()
                 .Bind<IPlatformSettings>().ToConstant(Instance)
+                .Bind<IRendererFactory>().ToConstant(ImmediateRenderer.Factory)
                 .Bind<IPlatformThreadingInterface>().ToConstant(new AndroidThreadingInterface())
                 .Bind<ISystemDialogImpl>().ToTransient<SystemDialogImpl>()
                 .Bind<IWindowingPlatform>().ToConstant(Instance)

+ 6 - 21
src/Android/Avalonia.Android/Avalonia.Android.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -41,18 +41,6 @@
     <Reference Include="System.Collections" />
     <Reference Include="System.Core" />
     <Reference Include="System.IO" />
-    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\System.Reactive.Core.3.0.0\lib\netstandard1.3\System.Reactive.Core.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\System.Reactive.Interfaces.3.0.0\lib\netstandard1.0\System.Reactive.Interfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.PlatformServices, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\netstandard1.3\System.Reactive.PlatformServices.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
     <Reference Include="System.Reflection" />
     <Reference Include="System.ObjectModel" />
     <Reference Include="System.Threading.Tasks" />
@@ -86,7 +74,6 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
-    <None Include="packages.config" />
     <None Include="Resources\AboutResources.txt" />
   </ItemGroup>
   <ItemGroup>
@@ -145,11 +132,9 @@
   <ItemGroup />
   <Import Project="..\..\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\..\build\Rx.props" />
+  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
+  <PropertyGroup Condition="'$(UseRoslynPathHack)' == ''">
+    <CscToolPath>$(MSBuildToolsPath)\Roslyn</CscToolPath>
+  </PropertyGroup>
 </Project>

+ 5 - 2
src/Android/Avalonia.Android/Resources/Resource.Designer.cs

@@ -40,11 +40,14 @@ namespace Avalonia.Android
 		public partial class String
 		{
 			
+			// aapt resource value: 0x7f020002
+			public static int ApplicationName = 2130837506;
+			
 			// aapt resource value: 0x7f020001
-			public static int ApplicationName = 2130837505;
+			public static int Hello = 2130837505;
 			
 			// aapt resource value: 0x7f020000
-			public static int Hello = 2130837504;
+			public static int library_name = 2130837504;
 			
 			static String()
 			{

+ 0 - 19
src/Android/Avalonia.Android/packages.config

@@ -1,19 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="System.Collections" version="4.0.11" targetFramework="monoandroid44" />
-  <package id="System.Collections.Concurrent" version="4.0.12" targetFramework="monoandroid44" />
-  <package id="System.ComponentModel" version="4.0.1" targetFramework="monoandroid44" />
-  <package id="System.Diagnostics.Debug" version="4.0.11" targetFramework="monoandroid44" />
-  <package id="System.Diagnostics.Tools" version="4.0.1" targetFramework="monoandroid44" />
-  <package id="System.Globalization" version="4.0.11" targetFramework="monoandroid44" />
-  <package id="System.Linq" version="4.1.0" targetFramework="monoandroid44" />
-  <package id="System.Reactive.Core" version="3.0.0" targetFramework="monoandroid44" />
-  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="monoandroid44" />
-  <package id="System.Reactive.PlatformServices" version="3.0.0" targetFramework="monoandroid44" />
-  <package id="System.Reflection" version="4.1.0" targetFramework="monoandroid44" />
-  <package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="monoandroid44" />
-  <package id="System.Runtime" version="4.1.0" targetFramework="monoandroid44" />
-  <package id="System.Runtime.Extensions" version="4.1.0" targetFramework="monoandroid44" />
-  <package id="System.Threading" version="4.0.11" targetFramework="monoandroid44" />
-  <package id="System.Threading.Tasks" version="4.0.11" targetFramework="monoandroid44" />
-</packages>

+ 6 - 36
src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj

@@ -1,5 +1,5 @@
 <?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <PropertyGroup>
     <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
     <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
@@ -64,35 +64,8 @@
   <ItemGroup>
     <Reference Include="Mono.Android" />
     <Reference Include="mscorlib" />
-    <Reference Include="Serilog, Version=1.5.0.0, Culture=neutral, PublicKeyToken=24c2f752a8e58a10, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\Serilog.1.5.14\lib\portable-net45+win+wpa81+wp80+MonoAndroid10+MonoTouch10\Serilog.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Splat, Version=1.6.2.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\Splat.1.6.2\lib\monoandroid\Splat.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Sprache, Version=2.1.0.0, Culture=neutral, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\Sprache.2.1.0\lib\netstandard1.0\Sprache.dll</HintPath>
-    </Reference>
     <Reference Include="System" />
     <Reference Include="System.Core" />
-    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\System.Reactive.Core.3.0.0\lib\netstandard1.3\System.Reactive.Core.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\System.Reactive.Interfaces.3.0.0\lib\netstandard1.0\System.Reactive.Interfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Linq, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\System.Reactive.Linq.3.0.0\lib\netstandard1.3\System.Reactive.Linq.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.PlatformServices, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\netstandard1.3\System.Reactive.PlatformServices.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
     <Reference Include="System.Xml.Linq" />
     <Reference Include="System.Xml" />
   </ItemGroup>
@@ -103,7 +76,6 @@
   </ItemGroup>
   <ItemGroup>
     <None Include="app.config" />
-    <None Include="packages.config" />
     <None Include="Resources\AboutResources.txt" />
     <None Include="Assets\AboutAssets.txt" />
   </ItemGroup>
@@ -181,11 +153,9 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-     Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\..\build\Serilog.props" />
+  <Import Project="..\..\..\build\Splat.props" />
+  <Import Project="..\..\..\build\Sprache.props" />
+  <Import Project="..\..\..\build\Rx.props" />
+  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 1 - 0
src/Android/Avalonia.AndroidTestApplication/Resources/Resource.Designer.cs

@@ -28,6 +28,7 @@ namespace Avalonia.AndroidTestApplication
 		{
 			global::Avalonia.Android.Resource.String.ApplicationName = global::Avalonia.AndroidTestApplication.Resource.String.ApplicationName;
 			global::Avalonia.Android.Resource.String.Hello = global::Avalonia.AndroidTestApplication.Resource.String.Hello;
+			global::Avalonia.Android.Resource.String.library_name = global::Avalonia.AndroidTestApplication.Resource.String.library_name;
 			global::Splat.Resource.String.library_name = global::Avalonia.AndroidTestApplication.Resource.String.library_name;
 		}
 		

+ 0 - 25
src/Android/Avalonia.AndroidTestApplication/packages.config

@@ -1,25 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="Serilog" version="1.5.14" targetFramework="monoandroid44" />
-  <package id="Splat" version="1.6.2" targetFramework="monoandroid51" />
-  <package id="Sprache" version="2.1.0" targetFramework="monoandroid44" />
-  <package id="System.Collections" version="4.0.11" targetFramework="monoandroid44" />
-  <package id="System.Collections.Concurrent" version="4.0.12" targetFramework="monoandroid44" />
-  <package id="System.ComponentModel" version="4.0.1" targetFramework="monoandroid44" />
-  <package id="System.Diagnostics.Debug" version="4.0.11" targetFramework="monoandroid44" />
-  <package id="System.Diagnostics.Tools" version="4.0.1" targetFramework="monoandroid44" />
-  <package id="System.Globalization" version="4.0.11" targetFramework="monoandroid44" />
-  <package id="System.Linq" version="4.1.0" targetFramework="monoandroid44" />
-  <package id="System.Reactive" version="3.0.0" targetFramework="monoandroid44" />
-  <package id="System.Reactive.Core" version="3.0.0" targetFramework="monoandroid44" />
-  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="monoandroid44" />
-  <package id="System.Reactive.Linq" version="3.0.0" targetFramework="monoandroid44" />
-  <package id="System.Reactive.PlatformServices" version="3.0.0" targetFramework="monoandroid44" />
-  <package id="System.Reflection" version="4.1.0" targetFramework="monoandroid44" />
-  <package id="System.Resources.ResourceManager" version="4.0.1" targetFramework="monoandroid44" />
-  <package id="System.Runtime" version="4.1.0" targetFramework="monoandroid44" />
-  <package id="System.Runtime.Extensions" version="4.1.0" targetFramework="monoandroid44" />
-  <package id="System.Text.RegularExpressions" version="4.1.0" targetFramework="monoandroid44" />
-  <package id="System.Threading" version="4.0.11" targetFramework="monoandroid44" />
-  <package id="System.Threading.Tasks" version="4.0.11" targetFramework="monoandroid44" />
-</packages>

+ 5 - 62
src/Avalonia.Animation/Avalonia.Animation.csproj

@@ -1,20 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avalonia.Animation</RootNamespace>
-    <AssemblyName>Avalonia.Animation</AssemblyName>
-    <DefaultLanguage>en-US</DefaultLanguage>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFramework>netstandard1.1</TargetFramework>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
     <DebugSymbols>true</DebugSymbols>
@@ -38,57 +25,13 @@
     <NoWarn>CS1591</NoWarn>
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
   </PropertyGroup>
-  <ItemGroup>
-    <!-- A reference to the entire .NET Framework is automatically included -->
-    <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj">
-      <Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
-      <Name>Avalonia.Base</Name>
-    </ProjectReference>
-  </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Shared\SharedAssemblyInfo.cs">
       <Link>Properties\SharedAssemblyInfo.cs</Link>
     </Compile>
-    <Compile Include="Animation`1.cs" />
-    <Compile Include="Animation.cs" />
-    <Compile Include="Animate.cs" />
-    <Compile Include="Animatable.cs" />
-    <Compile Include="AnimationExtensions.cs" />
-    <Compile Include="IEasing`1.cs" />
-    <Compile Include="LinearEasing.cs" />
-    <Compile Include="LinearDoubleEasing.cs" />
-    <Compile Include="IEasing.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="PropertyTransitions.cs" />
-    <Compile Include="PropertyTransition.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Core.3.0.0\lib\netstandard1.1\System.Reactive.Core.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Interfaces.3.0.0\lib\netstandard1.0\System.Reactive.Interfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Linq, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Linq.3.0.0\lib\netstandard1.1\System.Reactive.Linq.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.PlatformServices, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\netstandard1.0\System.Reactive.PlatformServices.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
   </ItemGroup>
   <ItemGroup>
-    <None Include="packages.config" />
+    <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
   </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Rx.props" />
 </Project>

+ 0 - 8
src/Avalonia.Animation/packages.config

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="System.Reactive" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Core" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Linq" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.PlatformServices" version="3.0.0" targetFramework="portable45-net45+win8" />
-</packages>

+ 5 - 51
src/Avalonia.Base/Avalonia.Base.csproj

@@ -1,22 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avalonia</RootNamespace>
-    <AssemblyName>Avalonia.Base</AssemblyName>
-    <DefaultLanguage>en-US</DefaultLanguage>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>
-    </NuGetPackageImportStamp>
+    <TargetFramework>netstandard1.1</TargetFramework>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
     <DebugSymbols>true</DebugSymbols>
@@ -127,37 +112,6 @@
     <Compile Include="Utilities\WeakSubscriptionManager.cs" />
     <Compile Include="Utilities\WeakTimer.cs" />
   </ItemGroup>
-  <ItemGroup>
-    <Reference Include="JetBrains.Annotations.PCL328, Version=10.0.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\JetBrains.Annotations.10.0.0\lib\portable-net4+sl5+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\JetBrains.Annotations.PCL328.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Core.3.0.0\lib\netstandard1.1\System.Reactive.Core.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Interfaces.3.0.0\lib\netstandard1.0\System.Reactive.Interfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Linq, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Linq.3.0.0\lib\netstandard1.1\System.Reactive.Linq.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.PlatformServices, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\netstandard1.0\System.Reactive.PlatformServices.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Rx.props" />
+  <Import Project="..\..\build\JetBrains.Annotations.props" />
 </Project>

+ 0 - 41
src/Avalonia.Base/AvaloniaDisposable.cs

@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Avalonia.Platform;
-
-namespace Avalonia
-{
-    public abstract class AvaloniaDisposable : IDisposable
-    {
-#if DEBUG_DISPOSE
-        public string DisposedAt { get; private set; }
-#endif
-
-
-        public bool IsDisposed { get; private set; }
-
-        public void Dispose()
-        {
-            IsDisposed = true;
-#if DEBUG_DISPOSE
-            DisposedAt = AvaloniaLocator.Current.GetService<IRuntimePlatform>().GetStackTrace();
-#endif
-            DoDispose();
-        }
-
-        protected void CheckDisposed()
-        {
-            if (IsDisposed)
-                throw new ObjectDisposedException(GetType().FullName
-#if DEBUG_DISPOSE
-                    , "Disposed at: \n" + DisposedAt
-#endif
-
-                    );
-        }
-
-        protected abstract void DoDispose();
-    }
-}

+ 7 - 4
src/Avalonia.Base/AvaloniaObject.cs

@@ -181,6 +181,7 @@ namespace Avalonia
         public void ClearValue(AvaloniaProperty property)
         {
             Contract.Requires<ArgumentNullException>(property != null);
+            VerifyAccess();
 
             SetValue(property, AvaloniaProperty.UnsetValue);
         }
@@ -193,6 +194,7 @@ namespace Avalonia
         public object GetValue(AvaloniaProperty property)
         {
             Contract.Requires<ArgumentNullException>(property != null);
+            VerifyAccess();
 
             if (property.IsDirect)
             {
@@ -234,7 +236,8 @@ namespace Avalonia
         public bool IsSet(AvaloniaProperty property)
         {
             Contract.Requires<ArgumentNullException>(property != null);
-            
+            VerifyAccess();
+
             PriorityValue value;
 
             if (_values.TryGetValue(property, out value))
@@ -575,13 +578,13 @@ namespace Avalonia
 
             if (notification == null)
             {
-                return TypeUtilities.CastOrDefault(value, type);
+                return TypeUtilities.ConvertImplicitOrDefault(value, type);
             }
             else
             {
                 if (notification.HasValue)
                 {
-                    notification.SetValue(TypeUtilities.CastOrDefault(notification.Value, type));
+                    notification.SetValue(TypeUtilities.ConvertImplicitOrDefault(notification.Value, type));
                 }
 
                 return notification;
@@ -732,7 +735,7 @@ namespace Avalonia
                 ThrowNotRegistered(property);
             }
 
-            if (!TypeUtilities.TryCast(property.PropertyType, value, out value))
+            if (!TypeUtilities.TryConvertImplicit(property.PropertyType, value, out value))
             {
                 throw new ArgumentException(string.Format(
                     "Invalid value for Property '{0}': '{1}' ({2})",

+ 1 - 1
src/Avalonia.Base/AvaloniaProperty.cs

@@ -476,7 +476,7 @@ namespace Avalonia
         /// <returns>True if the value is valid, otherwise false.</returns>
         public bool IsValidValue(object value)
         {
-            return TypeUtilities.TryCast(PropertyType, value, out value);
+            return TypeUtilities.TryConvertImplicit(PropertyType, value, out value);
         }
 
         /// <summary>

+ 5 - 0
src/Avalonia.Base/IPriorityValueOwner.cs

@@ -25,5 +25,10 @@ namespace Avalonia
         /// <param name="sender">The source of the change.</param>
         /// <param name="notification">The notification.</param>
         void BindingNotificationReceived(PriorityValue sender, BindingNotification notification);
+
+        /// <summary>
+        /// Ensures that the current thread is the UI thread.
+        /// </summary>
+        void VerifyAccess();
     }
 }

+ 2 - 0
src/Avalonia.Base/PriorityBindingEntry.cs

@@ -92,6 +92,8 @@ namespace Avalonia
 
         private void ValueChanged(object value)
         {
+            _owner.Owner.Owner?.VerifyAccess();
+
             var notification = value as BindingNotification;
 
             if (notification != null)

+ 11 - 7
src/Avalonia.Base/PriorityLevel.cs

@@ -33,7 +33,6 @@ namespace Avalonia
     /// </remarks>
     internal class PriorityLevel
     {
-        private PriorityValue _owner;
         private object _directValue;
         private int _nextIndex;
 
@@ -48,13 +47,18 @@ namespace Avalonia
         {
             Contract.Requires<ArgumentNullException>(owner != null);
 
-            _owner = owner;
+            Owner = owner;
             Priority = priority;
             Value = _directValue = AvaloniaProperty.UnsetValue;
             ActiveBindingIndex = -1;
             Bindings = new LinkedList<PriorityBindingEntry>();
         }
 
+        /// <summary>
+        /// Gets the owner of the level.
+        /// </summary>
+        public PriorityValue Owner { get; }
+
         /// <summary>
         /// Gets the priority of this level.
         /// </summary>
@@ -73,7 +77,7 @@ namespace Avalonia
             set
             {
                 Value = _directValue = value;
-                _owner.LevelValueChanged(this);
+                Owner.LevelValueChanged(this);
             }
         }
 
@@ -131,7 +135,7 @@ namespace Avalonia
                 {
                     Value = entry.Value;
                     ActiveBindingIndex = entry.Index;
-                    _owner.LevelValueChanged(this);
+                    Owner.LevelValueChanged(this);
                 }
                 else
                 {
@@ -161,7 +165,7 @@ namespace Avalonia
         /// <param name="error">The error.</param>
         public void Error(PriorityBindingEntry entry, BindingNotification error)
         {
-            _owner.LevelError(this, error);
+            Owner.LevelError(this, error);
         }
 
         /// <summary>
@@ -175,14 +179,14 @@ namespace Avalonia
                 {
                     Value = binding.Value;
                     ActiveBindingIndex = binding.Index;
-                    _owner.LevelValueChanged(this);
+                    Owner.LevelValueChanged(this);
                     return;
                 }
             }
 
             Value = DirectValue;
             ActiveBindingIndex = -1;
-            _owner.LevelValueChanged(this);
+            Owner.LevelValueChanged(this);
         }
     }
 }

+ 12 - 8
src/Avalonia.Base/PriorityValue.cs

@@ -26,7 +26,6 @@ namespace Avalonia
     /// </remarks>
     internal class PriorityValue
     {
-        private readonly IPriorityValueOwner _owner;
         private readonly Type _valueType;
         private readonly SingleOrDictionary<int, PriorityLevel> _levels = new SingleOrDictionary<int, PriorityLevel>();
         private object _value;
@@ -45,7 +44,7 @@ namespace Avalonia
             Type valueType,
             Func<object, object> validate = null)
         {
-            _owner = owner;
+            Owner = owner;
             Property = property;
             _valueType = valueType;
             _value = AvaloniaProperty.UnsetValue;
@@ -53,6 +52,11 @@ namespace Avalonia
             _validate = validate;
         }
 
+        /// <summary>
+        /// Gets the owner of the value.
+        /// </summary>
+        public IPriorityValueOwner Owner { get; }
+
         /// <summary>
         /// Gets the property that the value represents.
         /// </summary>
@@ -188,9 +192,9 @@ namespace Avalonia
             Logger.Log(
                 LogEventLevel.Error,
                 LogArea.Binding,
-                _owner,
+                Owner,
                 "Error in binding to {Target}.{Property}: {Message}",
-                _owner,
+                Owner,
                 Property,
                 error.Error.Message);
         }
@@ -245,7 +249,7 @@ namespace Avalonia
                 value = (notification.HasValue) ? notification.Value : null;
             }
 
-            if (TypeUtilities.TryCast(_valueType, value, out castValue))
+            if (TypeUtilities.TryConvertImplicit(_valueType, value, out castValue))
             {
                 var old = _value;
 
@@ -264,19 +268,19 @@ namespace Avalonia
 
                 if (notification == null || notification.HasValue)
                 {
-                    _owner?.Changed(this, old, _value);
+                    Owner?.Changed(this, old, _value);
                 }
 
                 if (notification != null)
                 {
-                    _owner?.BindingNotificationReceived(this, notification);
+                    Owner?.BindingNotificationReceived(this, notification);
                 }
             }
             else
             {
                 Logger.Error(
                     LogArea.Binding, 
-                    _owner,
+                    Owner,
                     "Binding produced invalid value for {$Property} ({$PropertyType}): {$Value} ({$ValueType})",
                     Property.Name, 
                     _valueType, 

+ 1 - 0
src/Avalonia.Base/Properties/AssemblyInfo.cs

@@ -6,4 +6,5 @@ using System.Runtime.CompilerServices;
 
 [assembly: AssemblyTitle("Avalonia.Base")]
 [assembly: InternalsVisibleTo("Avalonia.Base.UnitTests")]
+[assembly: InternalsVisibleTo("Avalonia.UnitTests")]
 [assembly: InternalsVisibleTo("DynamicProxyGenAssembly2")] 

+ 37 - 18
src/Avalonia.Base/Threading/Dispatcher.cs

@@ -15,10 +15,10 @@ namespace Avalonia.Threading
     /// In Avalonia, there is usually only a single <see cref="Dispatcher"/> in the application -
     /// the one for the UI thread, retrieved via the <see cref="UIThread"/> property.
     /// </remarks>
-    public class Dispatcher
+    public class Dispatcher : IDispatcher
     {
-        private readonly IPlatformThreadingInterface _platform;
         private readonly JobRunner _jobRunner;
+        private IPlatformThreadingInterface _platform;
 
         public static Dispatcher UIThread { get; } =
             new Dispatcher(AvaloniaLocator.Current.GetService<IPlatformThreadingInterface>());
@@ -26,22 +26,31 @@ namespace Avalonia.Threading
         public Dispatcher(IPlatformThreadingInterface platform)
         {
             _platform = platform;
-            if(_platform == null)
-                //TODO: Unit test mode, fix that somehow
-                return;
             _jobRunner = new JobRunner(platform);
-            _platform.Signaled += _jobRunner.RunJobs;
+
+            if (_platform != null)
+            {
+                _platform.Signaled += _jobRunner.RunJobs;
+            }
         }
 
+        /// <summary>
+        /// Checks that the current thread is the UI thread.
+        /// </summary>
         public bool CheckAccess() => _platform?.CurrentThreadIsLoopThread ?? true;
 
+        /// <summary>
+        /// Checks that the current thread is the UI thread and throws if not.
+        /// </summary>
+        /// <exception cref="InvalidOperationException">
+        /// The current thread is not the UI thread.
+        /// </exception>
         public void VerifyAccess()
         {
             if (!CheckAccess())
                 throw new InvalidOperationException("Call from invalid thread");
         }
 
-
         /// <summary>
         /// Runs the dispatcher's main loop.
         /// </summary>
@@ -63,25 +72,35 @@ namespace Avalonia.Threading
             _jobRunner?.RunJobs();
         }
 
-        /// <summary>
-        /// Invokes a method on the dispatcher thread.
-        /// </summary>
-        /// <param name="action">The method.</param>
-        /// <param name="priority">The priority with which to invoke the method.</param>
-        /// <returns>A task that can be used to track the method's execution.</returns>
+        /// <inheritdoc/>
         public Task InvokeTaskAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
         {
             return _jobRunner?.InvokeAsync(action, priority);
         }
 
-        /// <summary>
-        /// Post action that will be invoked on main thread
-        /// </summary>
-        /// <param name="action">The method.</param>
-        /// <param name="priority">The priority with which to invoke the method.</param>
+        /// <inheritdoc/>
         public void InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal)
         {
             _jobRunner?.Post(action, priority);
         }
+
+        /// <summary>
+        /// Allows unit tests to change the platform threading interface.
+        /// </summary>
+        internal void UpdateServices()
+        {
+            if (_platform != null)
+            {
+                _platform.Signaled -= _jobRunner.RunJobs;
+            }
+
+            _platform = AvaloniaLocator.Current.GetService<IPlatformThreadingInterface>();
+            _jobRunner.UpdateServices();
+
+            if (_platform != null)
+            {
+                _platform.Signaled += _jobRunner.RunJobs;
+            }
+        }
     }
 }

+ 39 - 0
src/Avalonia.Base/Threading/IDispatcher.cs

@@ -0,0 +1,39 @@
+using System;
+using System.Threading.Tasks;
+
+namespace Avalonia.Threading
+{
+    /// <summary>
+    /// Dispatches jobs to a thread.
+    /// </summary>
+    public interface IDispatcher
+    {
+        /// <summary>
+        /// Determines whether the calling thread is the thread associated with this <see cref="IDispatcher"/>.
+        /// </summary>
+        /// <returns>True if he calling thread is the thread associated with the dispatched, otherwise false.</returns>
+        bool CheckAccess();
+
+        /// <summary>
+        /// Throws an exception if the calling thread is not the thread associated with this <see cref="IDispatcher"/>.
+        /// </summary>
+        void VerifyAccess();
+
+        /// <summary>
+        /// Invokes a method on the dispatcher thread.
+        /// </summary>
+        /// <param name="action">The method.</param>
+        /// <param name="priority">The priority with which to invoke the method.</param>
+        /// <returns>A task that can be used to track the method's execution.</returns>
+        void InvokeAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal);
+
+        /// <summary>
+        /// Post action that will be invoked on main thread
+        /// </summary>
+        /// <param name="action">The method.</param>
+        /// <param name="priority">The priority with which to invoke the method.</param>
+        // TODO: The naming of this method is confusing: the Async suffix usually means return a task.
+        // Remove this and rename InvokeTaskAsync as InvokeAsync. See #816.
+        Task InvokeTaskAsync(Action action, DispatcherPriority priority = DispatcherPriority.Normal);
+    }
+}

+ 10 - 3
src/Avalonia.Base/Threading/JobRunner.cs

@@ -3,7 +3,6 @@
 
 using System;
 using System.Collections.Generic;
-using System.Threading;
 using System.Threading.Tasks;
 using Avalonia.Platform;
 
@@ -14,8 +13,8 @@ namespace Avalonia.Threading
     /// </summary>
     internal class JobRunner
     {
-        private readonly IPlatformThreadingInterface _platform;
         private readonly Queue<Job> _queue = new Queue<Job>();
+        private IPlatformThreadingInterface _platform;
 
         public JobRunner(IPlatformThreadingInterface platform)
         {
@@ -82,6 +81,14 @@ namespace Avalonia.Threading
             AddJob(new Job(action, priority, true));
         }
 
+        /// <summary>
+        /// Allows unit tests to change the platform threading interface.
+        /// </summary>
+        internal void UpdateServices()
+        {
+            _platform = AvaloniaLocator.Current.GetService<IPlatformThreadingInterface>();
+        }
+
         private void AddJob(Job job)
         {
             var needWake = false;
@@ -91,7 +98,7 @@ namespace Avalonia.Threading
                 _queue.Enqueue(job);
             }
             if (needWake)
-                _platform.Signal();
+                _platform?.Signal();
         }
 
         /// <summary>

+ 162 - 75
src/Avalonia.Base/Utilities/TypeUtilities.cs

@@ -14,17 +14,61 @@ namespace Avalonia.Utilities
     /// </summary>
     public static class TypeUtilities
     {
-        private static readonly Dictionary<Type, List<Type>> Conversions = new Dictionary<Type, List<Type>>()
+        private static int[] Conversions =
         {
-            { typeof(decimal), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char) } },
-            { typeof(double), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float) } },
-            { typeof(float), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(long), typeof(ulong), typeof(char), typeof(float) } },
-            { typeof(ulong), new List<Type> { typeof(byte), typeof(ushort), typeof(uint), typeof(char) } },
-            { typeof(long), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(int), typeof(uint), typeof(char) } },
-            { typeof(uint), new List<Type> { typeof(byte), typeof(ushort), typeof(char) } },
-            { typeof(int), new List<Type> { typeof(sbyte), typeof(byte), typeof(short), typeof(ushort), typeof(char) } },
-            { typeof(ushort), new List<Type> { typeof(byte), typeof(char) } },
-            { typeof(short), new List<Type> { typeof(byte) } }
+            0b101111111111101, // Boolean
+            0b100001111111110, // Char
+            0b101111111111111, // SByte
+            0b101111111111111, // Byte
+            0b101111111111111, // Int16
+            0b101111111111111, // UInt16
+            0b101111111111111, // Int32
+            0b101111111111111, // UInt32
+            0b101111111111111, // Int64
+            0b101111111111111, // UInt64
+            0b101111111111101, // Single
+            0b101111111111101, // Double
+            0b101111111111101, // Decimal
+            0b110000000000000, // DateTime
+            0b111111111111111, // String
+        };
+
+        private static int[] ImplicitConversions =
+        {
+            0b000000000000001, // Boolean
+            0b001110111100010, // Char
+            0b001110101010100, // SByte
+            0b001111111111000, // Byte
+            0b001110101010000, // Int16
+            0b001111111100000, // UInt16
+            0b001110101000000, // Int32
+            0b001111110000000, // UInt32
+            0b001110100000000, // Int64
+            0b001111000000000, // UInt64
+            0b000110000000000, // Single
+            0b000100000000000, // Double
+            0b001000000000000, // Decimal
+            0b010000000000000, // DateTime
+            0b100000000000000, // String
+        };
+
+        private static Type[] InbuiltTypes =
+        {
+            typeof(Boolean),
+            typeof(Char),
+            typeof(SByte),
+            typeof(Byte),
+            typeof(Int16),
+            typeof(UInt16),
+            typeof(Int32),
+            typeof(UInt32),
+            typeof(Int64),
+            typeof(UInt64),
+            typeof(Single),
+            typeof(Double),
+            typeof(Decimal),
+            typeof(DateTime),
+            typeof(String),
         };
 
         private static readonly Type[] NumericTypes = new[]
@@ -54,49 +98,104 @@ namespace Avalonia.Utilities
         }
 
         /// <summary>
-        /// Try to cast a value to a type, using implicit conversions if possible.
+        /// Try to convert a value to a type by any means possible.
         /// </summary>
         /// <param name="to">The type to cast to.</param>
         /// <param name="value">The value to cast.</param>
+        /// <param name="culture">The culture to use.</param>
         /// <param name="result">If sucessful, contains the cast value.</param>
         /// <returns>True if the cast was sucessful, otherwise false.</returns>
-        public static bool TryCast(Type to, object value, out object result)
+        public static bool TryConvert(Type to, object value, CultureInfo culture, out object result)
         {
-            Contract.Requires<ArgumentNullException>(to != null);
-
             if (value == null)
             {
                 result = null;
                 return AcceptsNull(to);
             }
 
-            var from = value.GetType();
-
             if (value == AvaloniaProperty.UnsetValue)
             {
                 result = value;
                 return true;
             }
-            else if (to.GetTypeInfo().IsAssignableFrom(from.GetTypeInfo()))
+
+            var from = value.GetType();
+            var fromTypeInfo = from.GetTypeInfo();
+            var toTypeInfo = to.GetTypeInfo();
+
+            if (toTypeInfo.IsAssignableFrom(fromTypeInfo))
             {
                 result = value;
                 return true;
             }
-            else if (Conversions.ContainsKey(to) && Conversions[to].Contains(from))
+
+            if (to == typeof(string))
             {
-                result = Convert.ChangeType(value, to);
+                result = Convert.ToString(value);
                 return true;
             }
-            else
+
+            if (toTypeInfo.IsEnum && from == typeof(string))
+            {
+                if (Enum.IsDefined(to, (string)value))
+                {
+                    result = Enum.Parse(to, (string)value);
+                    return true;
+                }
+            }
+
+            if (!fromTypeInfo.IsEnum && toTypeInfo.IsEnum)
             {
-                var cast = from.GetRuntimeMethods()
-                    .FirstOrDefault(m => m.Name == "op_Implicit" && m.ReturnType == to);
+                result = null;
+
+                if (TryConvert(Enum.GetUnderlyingType(to), value, culture, out object enumValue))
+                {
+                    result = Enum.ToObject(to, enumValue);
+                    return true;
+                }
+            }
 
-                if (cast != null)
+            if (fromTypeInfo.IsEnum && IsNumeric(to))
+            {
+                try
                 {
-                    result = cast.Invoke(null, new[] { value });
+                    result = Convert.ChangeType((int)value, to, culture);
                     return true;
                 }
+                catch
+                {
+                    result = null;
+                    return false;
+                }
+            }
+
+            var convertableFrom = Array.IndexOf(InbuiltTypes, from);
+            var convertableTo = Array.IndexOf(InbuiltTypes, to);
+
+            if (convertableFrom != -1 && convertableTo != -1)
+            {
+                if ((Conversions[convertableFrom] & 1 << convertableTo) != 0)
+                {
+                    try
+                    {
+                        result = Convert.ChangeType(value, to, culture);
+                        return true;
+                    }
+                    catch
+                    {
+                        result = null;
+                        return false;
+                    }
+                }
+            }
+
+            var cast = from.GetRuntimeMethods()
+                .FirstOrDefault(m => (m.Name == "op_Implicit" || m.Name == "op_Explicit") && m.ReturnType == to);
+
+            if (cast != null)
+            {
+                result = cast.Invoke(null, new[] { value });
+                return true;
             }
 
             result = null;
@@ -104,15 +203,14 @@ namespace Avalonia.Utilities
         }
 
         /// <summary>
-        /// Try to convert a value to a type, using <see cref="System.Convert"/> if possible,
-        /// otherwise using <see cref="TryCast(Type, object, out object)"/>.
+        /// Try to convert a value to a type using the implicit conversions allowed by the C#
+        /// language.
         /// </summary>
         /// <param name="to">The type to cast to.</param>
         /// <param name="value">The value to cast.</param>
-        /// <param name="culture">The culture to use.</param>
         /// <param name="result">If sucessful, contains the cast value.</param>
         /// <returns>True if the cast was sucessful, otherwise false.</returns>
-        public static bool TryConvert(Type to, object value, CultureInfo culture, out object result)
+        public static bool TryConvertImplicit(Type to, object value, out object result)
         {
             if (value == null)
             {
@@ -120,54 +218,44 @@ namespace Avalonia.Utilities
                 return AcceptsNull(to);
             }
 
-            var from = value.GetType();
-
             if (value == AvaloniaProperty.UnsetValue)
             {
                 result = value;
                 return true;
             }
 
-            if (to.GetTypeInfo().IsAssignableFrom(from.GetTypeInfo()))
-            {
-                result = value;
-                return true;
-            }
+            var from = value.GetType();
+            var fromTypeInfo = from.GetTypeInfo();
+            var toTypeInfo = to.GetTypeInfo();
 
-            if (to == typeof(string))
+            if (toTypeInfo.IsAssignableFrom(fromTypeInfo))
             {
-                result = Convert.ToString(value);
+                result = value;
                 return true;
             }
 
-            if (to.GetTypeInfo().IsEnum && from == typeof(string))
-            {
-                if (Enum.IsDefined(to, (string)value))
-                {
-                    result = Enum.Parse(to, (string)value);
-                    return true;
-                }
-            }
-
-            bool containsFrom = Conversions.ContainsKey(from);
-            bool containsTo = Conversions.ContainsKey(to);
+            var convertableFrom = Array.IndexOf(InbuiltTypes, from);
+            var convertableTo = Array.IndexOf(InbuiltTypes, to);
 
-            if ((containsFrom && containsTo) || (from == typeof(string) && containsTo))
+            if (convertableFrom != -1 && convertableTo != -1)
             {
-                try
-                {
-                    result = Convert.ChangeType(value, to, culture);
-                    return true;
-                }
-                catch
+                if ((ImplicitConversions[convertableFrom] & 1 << convertableTo) != 0)
                 {
-                    result = null;
-                    return false;
+                    try
+                    {
+                        result = Convert.ChangeType(value, to, CultureInfo.InvariantCulture);
+                        return true;
+                    }
+                    catch
+                    {
+                        result = null;
+                        return false;
+                    }
                 }
             }
 
             var cast = from.GetRuntimeMethods()
-                .FirstOrDefault(m => (m.Name == "op_Implicit" || m.Name == "op_Explicit") && m.ReturnType == to);
+                .FirstOrDefault(m => m.Name == "op_Implicit" && m.ReturnType == to);
 
             if (cast != null)
             {
@@ -180,29 +268,28 @@ namespace Avalonia.Utilities
         }
 
         /// <summary>
-        /// Casts a value to a type, returning the default for that type if the value could not be
-        /// cast.
+        /// Convert a value to a type by any means possible, returning the default for that type
+        /// if the value could not be converted.
         /// </summary>
         /// <param name="value">The value to cast.</param>
         /// <param name="type">The type to cast to..</param>
+        /// <param name="culture">The culture to use.</param>
         /// <returns>A value of <paramref name="type"/>.</returns>
-        public static object CastOrDefault(object value, Type type)
+        public static object ConvertOrDefault(object value, Type type, CultureInfo culture)
         {
-            var typeInfo = type.GetTypeInfo();
-            object result;
+            return TryConvert(type, value, culture, out object result) ? result : Default(type);
+        }
 
-            if (TypeUtilities.TryCast(type, value, out result))
-            {
-                return result;
-            }
-            else if (typeInfo.IsValueType)
-            {
-                return Activator.CreateInstance(type);
-            }
-            else
-            {
-                return null;
-            }
+        /// <summary>
+        /// Convert a value to a type using the implicit conversions allowed by the C# language or
+        /// return the default for the type if the value could not be converted.
+        /// </summary>
+        /// <param name="value">The value to cast.</param>
+        /// <param name="type">The type to cast to..</param>
+        /// <returns>A value of <paramref name="type"/>.</returns>
+        public static object ConvertImplicitOrDefault(object value, Type type)
+        {
+            return TryConvertImplicit(type, value, out object result) ? result : Default(type);
         }
 
         /// <summary>

+ 0 - 9
src/Avalonia.Base/packages.config

@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="JetBrains.Annotations" version="10.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Core" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Linq" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.PlatformServices" version="3.0.0" targetFramework="portable45-net45+win8" />
-</packages>

+ 12 - 248
src/Avalonia.Controls/Avalonia.Controls.csproj

@@ -1,22 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{D2221C82-4A25-4583-9B43-D791E3F6820C}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avalonia.Controls</RootNamespace>
-    <AssemblyName>Avalonia.Controls</AssemblyName>
-    <DefaultLanguage>en-US</DefaultLanguage>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>
-    </NuGetPackageImportStamp>
+    <TargetFramework>netstandard1.1</TargetFramework>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
     <DebugSymbols>true</DebugSymbols>
@@ -44,237 +29,16 @@
     <Compile Include="..\Shared\SharedAssemblyInfo.cs">
       <Link>Properties\SharedAssemblyInfo.cs</Link>
     </Compile>
-    <Compile Include="AppBuilderBase.cs" />
-    <Compile Include="Application.cs" />
-    <Compile Include="Classes.cs" />
-    <Compile Include="ContextMenu.cs" />
-    <Compile Include="Design.cs" />
-    <Compile Include="DockPanel.cs" />
-    <Compile Include="Expander.cs" />
-    <Compile Include="Generators\ItemContainerInfo.cs" />
-    <Compile Include="Generators\MenuItemContainerGenerator.cs" />
-    <Compile Include="Generators\TreeContainerIndex.cs" />
-    <Compile Include="HotkeyManager.cs" />
-    <Compile Include="IApplicationLifecycle.cs" />
-    <Compile Include="IScrollable.cs" />
-    <Compile Include="Platform\IWindowBaseImpl.cs" />
-    <Compile Include="Platform\Surfaces\IFramebufferPlatformSurface.cs" />
-    <Compile Include="PointEventArgs.cs" />
-    <Compile Include="Embedding\EmbeddableControlRoot.cs" />
-    <Compile Include="Platform\IEmbeddableWindowImpl.cs" />
-    <Compile Include="Platform\ExportAvaloniaModuleAttribute.cs" />
-    <Compile Include="Platform\ExportWindowingSubsystemAttribute.cs" />
-    <Compile Include="WindowBase.cs" />
-    <Compile Include="WindowIcon.cs" />
-    <Compile Include="IPseudoClasses.cs" />
-    <Compile Include="DropDownItem.cs" />
-    <Compile Include="ISetInheritanceParent.cs" />
-    <Compile Include="ItemVirtualizationMode.cs" />
-    <Compile Include="IVirtualizingController.cs" />
-    <Compile Include="IVirtualizingPanel.cs" />
-    <Compile Include="LayoutTransformControl.cs" />
-    <Compile Include="Mixins\ContentControlMixin.cs" />
-    <Compile Include="Platform\IWindowIconImpl.cs" />
-    <Compile Include="Platform\IPlatformIconLoader.cs" />
-    <Compile Include="Platform\IWindowingPlatform.cs" />
-    <Compile Include="Platform\PlatformManager.cs" />
-    <Compile Include="Presenters\IContentPresenterHost.cs" />
-    <Compile Include="Presenters\IItemsPresenterHost.cs" />
-    <Compile Include="Presenters\ItemsPresenterBase.cs" />
-    <Compile Include="Presenters\ItemVirtualizerNone.cs" />
-    <Compile Include="Presenters\ItemVirtualizerSimple.cs" />
-    <Compile Include="Presenters\ItemVirtualizer.cs" />
-    <Compile Include="Primitives\HeaderedSelectingControl.cs" />
-    <Compile Include="Primitives\ILogicalScrollable.cs" />
-    <Compile Include="Primitives\TabStripItem.cs" />
-    <Compile Include="Primitives\TemplateAppliedEventArgs.cs" />
-    <Compile Include="SelectionChangedEventArgs.cs" />
-    <Compile Include="SelectionMode.cs" />
-    <Compile Include="Separator.cs" />
-    <Compile Include="Shapes\Line.cs" />
-    <Compile Include="Shapes\Polygon.cs" />
-    <Compile Include="Shapes\Polyline.cs" />
-    <Compile Include="Slider.cs" />
-    <Compile Include="SystemDialog.cs" />
-    <Compile Include="Generators\ITreeItemContainerGenerator.cs" />
-    <Compile Include="Generators\ItemContainerEventArgs.cs" />
-    <Compile Include="IContentControl.cs" />
-    <Compile Include="IControl.cs" />
-    <Compile Include="IPanel.cs" />
-    <Compile Include="ISetLogicalParent.cs" />
-    <Compile Include="MenuItemAccessKeyHandler.cs" />
-    <Compile Include="Mixins\SelectableMixin.cs" />
-    <Compile Include="Platform\ISystemDialogImpl.cs" />
-    <Compile Include="Presenters\IContentPresenter.cs" />
-    <Compile Include="Primitives\AccessText.cs" />
-    <Compile Include="Border.cs" />
-    <Compile Include="MenuItem.cs" />
-    <Compile Include="Menu.cs" />
-    <Compile Include="Button.cs" />
-    <Compile Include="DropDown.cs" />
-    <Compile Include="Carousel.cs" />
-    <Compile Include="Platform\IPopupImpl.cs" />
-    <Compile Include="Platform\ITopLevelImpl.cs" />
-    <Compile Include="PlacementMode.cs" />
-    <Compile Include="Primitives\Popup.cs" />
-    <Compile Include="Canvas.cs" />
-    <Compile Include="Templates\FuncControlTemplate`2.cs" />
-    <Compile Include="Templates\FuncDataTemplate`1.cs" />
-    <Compile Include="Templates\FuncMemberSelector.cs" />
-    <Compile Include="Templates\IControlTemplate.cs" />
-    <Compile Include="Templates\FuncTemplate`2.cs" />
-    <Compile Include="Templates\FuncTemplate`1.cs" />
-    <Compile Include="Templates\IDataTemplate.cs" />
-    <Compile Include="Presenters\IItemsPresenter.cs" />
-    <Compile Include="Presenters\IPresenter.cs" />
-    <Compile Include="Presenters\CarouselPresenter.cs" />
-    <Compile Include="Primitives\AdornerDecorator.cs" />
-    <Compile Include="Primitives\AdornerLayer.cs" />
-    <Compile Include="Primitives\RangeBase.cs" />
-    <Compile Include="ProgressBar.cs" />
-    <Compile Include="RadioButton.cs" />
-    <Compile Include="CheckBox.cs" />
-    <Compile Include="ColumnDefinition.cs" />
-    <Compile Include="ColumnDefinitions.cs" />
-    <Compile Include="ContentControl.cs" />
-    <Compile Include="GridSplitter.cs" />
-    <Compile Include="ISelectable.cs" />
-    <Compile Include="ListBoxItem.cs" />
-    <Compile Include="ListBox.cs" />
-    <Compile Include="Platform\IWindowImpl.cs" />
-    <Compile Include="Presenters\ScrollContentPresenter.cs" />
-    <Compile Include="Presenters\ContentPresenter.cs" />
-    <Compile Include="Control.cs" />
-    <Compile Include="ControlExtensions.cs" />
-    <Compile Include="Controls.cs" />
-    <Compile Include="Templates\FuncControlTemplate.cs" />
-    <Compile Include="Templates\DataTemplateExtensions.cs" />
-    <Compile Include="Templates\FuncDataTemplate.cs" />
-    <Compile Include="Generators\TreeItemContainerGenerator.cs" />
-    <Compile Include="Generators\ItemContainerGenerator`1.cs" />
-    <Compile Include="Generators\ItemContainerGenerator.cs" />
-    <Compile Include="IGlobalDataTemplates.cs" />
-    <Compile Include="Templates\DataTemplates.cs" />
-    <Compile Include="Decorator.cs" />
-    <Compile Include="DefinitionBase.cs" />
-    <Compile Include="Grid.cs" />
-    <Compile Include="GridLength.cs" />
-    <Compile Include="Primitives\HeaderedContentControl.cs" />
-    <Compile Include="Primitives\HeaderedItemsControl.cs" />
-    <Compile Include="IHeadered.cs" />
-    <Compile Include="Image.cs" />
-    <Compile Include="Generators\IItemContainerGenerator.cs" />
-    <Compile Include="ItemsControl.cs" />
-    <Compile Include="Presenters\ItemsPresenter.cs" />
-    <Compile Include="Panel.cs" />
-    <Compile Include="Primitives\ScrollBarVisibility.cs" />
-    <Compile Include="Primitives\Track.cs" />
-    <Compile Include="Primitives\Thumb.cs" />
-    <Compile Include="RequestBringIntoViewEventArgs.cs" />
-    <Compile Include="Shapes\Ellipse.cs" />
-    <Compile Include="Templates\IMemberSelector.cs" />
-    <Compile Include="Templates\ITemplate`2.cs" />
-    <Compile Include="Templates\ITemplate`1.cs" />
-    <Compile Include="Templates\ITreeDataTemplate.cs" />
-    <Compile Include="Templates\FuncTreeDataTemplate.cs" />
-    <Compile Include="ToolTip.cs" />
-    <Compile Include="UserControl.cs" />
-    <Compile Include="Templates\TemplateExtensions.cs" />
-    <Compile Include="Utils\AncestorFinder.cs" />
-    <Compile Include="Utils\IEnumerableUtils.cs" />
-    <Compile Include="Utils\StringUtils.cs" />
-    <Compile Include="TopLevel.cs" />
-    <Compile Include="Primitives\PopupRoot.cs" />
-    <Compile Include="Utils\UndoRedoHelper.cs" />
-    <Compile Include="VirtualizingStackPanel.cs" />
-    <Compile Include="WindowState.cs" />
-    <Compile Include="Window.cs" />
-    <Compile Include="RowDefinition.cs" />
-    <Compile Include="RowDefinitions.cs" />
-    <Compile Include="Primitives\SelectingItemsControl.cs" />
-    <Compile Include="ScrollViewer.cs" />
-    <Compile Include="Shapes\Path.cs" />
-    <Compile Include="Shapes\Rectangle.cs" />
-    <Compile Include="Shapes\Shape.cs" />
-    <Compile Include="Primitives\ScrollBar.cs" />
-    <Compile Include="StackPanel.cs" />
-    <Compile Include="TabControl.cs" />
-    <Compile Include="TabItem.cs" />
-    <Compile Include="Primitives\TabStrip.cs" />
-    <Compile Include="Primitives\TemplatedControl.cs" />
-    <Compile Include="TextBlock.cs" />
-    <Compile Include="TextBox.cs" />
-    <Compile Include="Presenters\TextPresenter.cs" />
-    <Compile Include="Primitives\ToggleButton.cs" />
-    <Compile Include="Templates\FuncTreeDataTemplate`1.cs" />
-    <Compile Include="TreeView.cs" />
-    <Compile Include="TreeViewItem.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="WindowEdge.cs" />
-    <Compile Include="WrapPanel.cs" />
   </ItemGroup>
   <ItemGroup>
-    <Reference Include="JetBrains.Annotations.PCL328, Version=10.0.0.0, Culture=neutral, PublicKeyToken=1010a0d8d6380325, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\JetBrains.Annotations.10.0.0\lib\portable-net4+sl5+netcore45+wpa81+wp8+MonoAndroid1+MonoTouch1\JetBrains.Annotations.PCL328.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Core.3.0.0\lib\netstandard1.1\System.Reactive.Core.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Interfaces.3.0.0\lib\netstandard1.0\System.Reactive.Interfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Linq, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Linq.3.0.0\lib\netstandard1.1\System.Reactive.Linq.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.PlatformServices, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\netstandard1.0\System.Reactive.PlatformServices.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
+    <ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj" />
+    <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
+    <ProjectReference Include="..\Avalonia.Input\Avalonia.Input.csproj" />
+    <ProjectReference Include="..\Avalonia.Interactivity\Avalonia.Interactivity.csproj" />
+    <ProjectReference Include="..\Avalonia.Layout\Avalonia.Layout.csproj" />
+    <ProjectReference Include="..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
+    <ProjectReference Include="..\Avalonia.Styling\Avalonia.Styling.csproj" />
   </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj">
-      <Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
-      <Name>Avalonia.Animation</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj">
-      <Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
-      <Name>Avalonia.Base</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Input\Avalonia.Input.csproj">
-      <Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
-      <Name>Avalonia.Input</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
-      <Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
-      <Name>Avalonia.Interactivity</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Layout\Avalonia.Layout.csproj">
-      <Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
-      <Name>Avalonia.Layout</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Visuals\Avalonia.Visuals.csproj">
-      <Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
-      <Name>Avalonia.Visuals</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Styling\Avalonia.Styling.csproj">
-      <Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
-      <Name>Avalonia.Styling</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup />
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Rx.props" />
+  <Import Project="..\..\build\JetBrains.Annotations.props" />
 </Project>

+ 1 - 1
src/Avalonia.Controls/Button.cs

@@ -226,7 +226,7 @@ namespace Avalonia.Controls
         }
 
         /// <inheritdoc/>
-        protected override void OnPointerReleased(PointerEventArgs e)
+        protected override void OnPointerReleased(PointerReleasedEventArgs e)
         {
             base.OnPointerReleased(e);
 

+ 35 - 1
src/Avalonia.Controls/Control.cs

@@ -17,7 +17,9 @@ using Avalonia.Input;
 using Avalonia.Interactivity;
 using Avalonia.Logging;
 using Avalonia.LogicalTree;
+using Avalonia.Rendering;
 using Avalonia.Styling;
+using Avalonia.VisualTree;
 
 namespace Avalonia.Controls
 {
@@ -33,7 +35,7 @@ namespace Avalonia.Controls
     /// - Implements <see cref="IStyleable"/> to allow styling to work on the control.
     /// - Implements <see cref="ILogical"/> to form part of a logical tree.
     /// </remarks>
-    public class Control : InputElement, IControl, INamed, ISetInheritanceParent, ISetLogicalParent, ISupportInitialize
+    public class Control : InputElement, IControl, INamed, ISetInheritanceParent, ISetLogicalParent, ISupportInitialize, IVisualBrushInitialize
     {
         /// <summary>
         /// Defines the <see cref="DataContext"/> property.
@@ -470,6 +472,38 @@ namespace Avalonia.Controls
             InheritanceParent = parent;
         }
 
+        /// <inheritdoc/>
+        void IVisualBrushInitialize.EnsureInitialized()
+        {
+            if (VisualRoot == null)
+            {
+                if (!IsInitialized)
+                {
+                    foreach (var i in this.GetSelfAndVisualDescendents())
+                    {
+                        var c = i as IControl;
+
+                        if (c?.IsInitialized == false)
+                        {
+                            var init = c as ISupportInitialize;
+
+                            if (init != null)
+                            {
+                                init.BeginInit();
+                                init.EndInit();
+                            }
+                        }
+                    }
+                }
+
+                if (!IsArrangeValid)
+                {
+                    Measure(Size.Infinity);
+                    Arrange(new Rect(DesiredSize));
+                }
+            }
+        }
+
         /// <summary>
         /// Adds a pseudo-class to be set when a property is true.
         /// </summary>

+ 13 - 14
src/Avalonia.Controls/Presenters/TextPresenter.cs

@@ -127,11 +127,11 @@ namespace Avalonia.Controls.Presenters
             base.Render(context);
 
             if (selectionStart == selectionEnd)
-            {                
+            {
                 var backgroundColor = (((Control)TemplatedParent).GetValue(BackgroundProperty) as SolidColorBrush)?.Color;
                 var caretBrush = Brushes.Black;
 
-                if(backgroundColor.HasValue)
+                if (backgroundColor.HasValue)
                 {
                     byte red = (byte)~(backgroundColor.Value.R);
                     byte green = (byte)~(backgroundColor.Value.G);
@@ -139,7 +139,7 @@ namespace Avalonia.Controls.Presenters
 
                     caretBrush = new SolidColorBrush(Color.FromRgb(red, green, blue));
                 }
-                
+
                 if (_caretBlink)
                 {
                     var charPos = FormattedText.HitTestTextPosition(CaretIndex);
@@ -212,7 +212,10 @@ namespace Avalonia.Controls.Presenters
 
             if (length > 0)
             {
-                result.SetForegroundBrush(Brushes.White, start, length);
+                result.Spans = new[]
+                {
+                    new FormattedTextStyleSpan(start, length, foregroundBrush: Brushes.White),
+                };
             }
 
             return result;
@@ -228,17 +231,13 @@ namespace Avalonia.Controls.Presenters
             }
             else
             {
-                // TODO: Pretty sure that measuring "X" isn't the right way to do this...
-                using (var formattedText = new FormattedText(
-                    "X",
-                    FontFamily,
-                    FontSize,
-                    FontStyle,
-                    TextAlignment,
-                    FontWeight))
+                return new FormattedText
                 {
-                    return formattedText.Measure();
-                }
+                    Text = "X",
+                    Typeface = new Typeface(FontFamily, FontSize, FontStyle, FontWeight),
+                    TextAlignment = TextAlignment,
+                    Constraint = availableSize,
+                }.Measure();
             }
         }
 

+ 8 - 9
src/Avalonia.Controls/Primitives/AccessText.cs

@@ -85,15 +85,14 @@ namespace Avalonia.Controls.Primitives
         /// <returns>A <see cref="FormattedText"/> object.</returns>
         protected override FormattedText CreateFormattedText(Size constraint)
         {
-            var result = new FormattedText(
-                StripAccessKey(Text),
-                FontFamily,
-                FontSize,
-                FontStyle,
-                TextAlignment,
-                FontWeight);
-            result.Constraint = constraint;
-            return result;
+            return new FormattedText
+            {
+                Constraint = constraint,
+                Typeface = new Typeface(FontFamily, FontSize, FontStyle, FontWeight),
+                Text = StripAccessKey(Text),
+                TextAlignment = TextAlignment,
+                Wrapping = TextWrapping,
+            };
         }
 
         /// <summary>

+ 1 - 31
src/Avalonia.Controls/Primitives/PopupRoot.cs

@@ -70,32 +70,12 @@ namespace Avalonia.Controls.Primitives
             this.PlatformImpl.Dispose();
         }
 
-        /// <summary>
-        /// Hides the popup.
-        /// </summary>
-        public void Hide()
-        {
-            PlatformImpl.Hide();
-            IsVisible = false;
-        }
-
-        /// <summary>
-        /// Shows the popup.
-        /// </summary>
-        public void Show()
-        {
-            EnsureInitialized();
-            PlatformImpl.Show();
-            LayoutManager.Instance.ExecuteInitialLayoutPass(this);
-            IsVisible = true;
-        }
-
         /// <inheritdoc/>
         protected override void OnTemplateApplied(TemplateAppliedEventArgs e)
         {
             base.OnTemplateApplied(e);
 
-            if (Parent.TemplatedParent != null)
+            if (Parent?.TemplatedParent != null)
             {
                 if (_presenterSubscription != null)
                 {
@@ -109,16 +89,6 @@ namespace Avalonia.Controls.Primitives
             }
         }
 
-        private void EnsureInitialized()
-        {
-            if (!this.IsInitialized)
-            {
-                var init = (ISupportInitialize)this;
-                init.BeginInit();
-                init.EndInit();
-            }
-        }
-
         private void SetTemplatedParentAndApplyChildTemplates(IControl control)
         {
             var templatedParent = Parent.TemplatedParent;

+ 1 - 1
src/Avalonia.Controls/Primitives/Thumb.cs

@@ -86,7 +86,7 @@ namespace Avalonia.Controls.Primitives
             RaiseEvent(ev);
         }
 
-        protected override void OnPointerReleased(PointerEventArgs e)
+        protected override void OnPointerReleased(PointerReleasedEventArgs e)
         {
             if (_lastPoint.HasValue)
             {

+ 9 - 12
src/Avalonia.Controls/TextBlock.cs

@@ -116,7 +116,7 @@ namespace Avalonia.Controls
                 this.GetObservable(TextAlignmentProperty).Select(_ => Unit.Default),
                 this.GetObservable(FontSizeProperty).Select(_ => Unit.Default),
                 this.GetObservable(FontStyleProperty).Select(_ => Unit.Default),
-                this.GetObservable(FontWeightProperty).Select(_=>Unit.Default))
+                this.GetObservable(FontWeightProperty).Select(_ => Unit.Default))
                 .Subscribe(_ =>
                 {
                     InvalidateFormattedText();
@@ -350,16 +350,14 @@ namespace Avalonia.Controls
         /// <returns>A <see cref="FormattedText"/> object.</returns>
         protected virtual FormattedText CreateFormattedText(Size constraint)
         {
-            var result = new FormattedText(
-                Text ?? string.Empty,
-                FontFamily,
-                FontSize,
-                FontStyle,
-                TextAlignment,
-                FontWeight,
-                TextWrapping);
-            result.Constraint = constraint;
-            return result;
+            return new FormattedText
+            {
+                Constraint = constraint,
+                Typeface = new Typeface(FontFamily, FontSize, FontStyle, FontWeight),
+                Text = Text ?? string.Empty,
+                TextAlignment = TextAlignment,
+                Wrapping = TextWrapping,
+            };
         }
 
         /// <summary>
@@ -370,7 +368,6 @@ namespace Avalonia.Controls
             if (_formattedText != null)
             {
                 _constraint = _formattedText.Constraint;
-                _formattedText.Dispose();
                 _formattedText = null;
             }
 

+ 1 - 1
src/Avalonia.Controls/TextBox.cs

@@ -522,7 +522,7 @@ namespace Avalonia.Controls
             }
         }
 
-        protected override void OnPointerReleased(PointerEventArgs e)
+        protected override void OnPointerReleased(PointerReleasedEventArgs e)
         {
             if (_presenter != null && e.Device.Captured == _presenter)
             {

+ 25 - 15
src/Avalonia.Controls/TopLevel.cs

@@ -96,10 +96,10 @@ namespace Avalonia.Controls
 
             PlatformImpl.Closed = HandleClosed;
             PlatformImpl.Input = HandleInput;
-            PlatformImpl.Paint = Renderer != null ? (Action<Rect>)Renderer.Render : null;
+            PlatformImpl.Paint = HandlePaint;
             PlatformImpl.Resized = HandleResized;
             PlatformImpl.ScalingChanged = HandleScalingChanged;
-            
+
 
             _keyboardNavigationHandler?.SetOwner(this);
             _accessKeyHandler?.SetOwner(this);
@@ -184,8 +184,10 @@ namespace Avalonia.Controls
             get { return AvaloniaLocator.Current.GetService<IGlobalStyles>(); }
         }
 
+        IRenderTarget IRenderRoot.CreateRenderTarget() => CreateRenderTarget();
+
         /// <inheritdoc/>
-        IRenderTarget IRenderRoot.CreateRenderTarget()
+        protected virtual IRenderTarget CreateRenderTarget()
         {
             return _renderInterface.CreateRenderTarget(PlatformImpl.Surfaces);
         }
@@ -208,6 +210,25 @@ namespace Avalonia.Controls
             return PlatformImpl.PointToScreen(p);
         }
 
+        /// <summary>
+        /// Handles a paint notification from <see cref="ITopLevelImpl.Resized"/>.
+        /// </summary>
+        /// <param name="rect">The dirty area.</param>
+        protected virtual void HandlePaint(Rect rect)
+        {
+            Renderer?.Paint(rect);
+        }
+
+        /// <summary>
+        /// Handles a closed notification from <see cref="ITopLevelImpl.Closed"/>.
+        /// </summary>
+        protected virtual void HandleClosed()
+        {
+            Closed?.Invoke(this, EventArgs.Empty);
+            Renderer?.Dispose();
+            Renderer = null;
+            _applicationLifecycle.OnExit -= OnApplicationExiting;
+        }
 
         /// <summary>
         /// Handles a resize notification from <see cref="ITopLevelImpl.Resized"/>.
@@ -219,7 +240,7 @@ namespace Avalonia.Controls
             Width = clientSize.Width;
             Height = clientSize.Height;
             LayoutManager.Instance.ExecuteLayoutPass();
-            PlatformImpl.Invalidate(new Rect(clientSize));
+            Renderer?.Resized(clientSize);
         }
 
         /// <summary>
@@ -267,17 +288,6 @@ namespace Avalonia.Controls
             return result;
         }
 
-        /// <summary>
-        /// Handles a closed notification from <see cref="ITopLevelImpl.Closed"/>.
-        /// </summary>
-        private void HandleClosed()
-        {
-            Closed?.Invoke(this, EventArgs.Empty);
-            Renderer?.Dispose();
-            Renderer = null;
-            _applicationLifecycle.OnExit -= OnApplicationExiting;
-        }
-
         private void OnApplicationExiting(object sender, EventArgs args)
         {
             HandleApplicationExiting();

+ 0 - 1
src/Avalonia.Controls/Utils/UndoRedoHelper.cs

@@ -3,7 +3,6 @@ using System.Collections.Generic;
 using System.Linq;
 using System.Text;
 using System.Threading.Tasks;
-using JetBrains.Annotations;
 using Avalonia.Utilities;
 
 namespace Avalonia.Controls.Utils

+ 31 - 13
src/Avalonia.Controls/Window.cs

@@ -11,6 +11,7 @@ using Avalonia.Media;
 using Avalonia.Platform;
 using Avalonia.Styling;
 using System.Collections.Generic;
+using System.Linq;
 
 namespace Avalonia.Controls
 {
@@ -189,6 +190,7 @@ namespace Avalonia.Controls
         {
             s_windows.Remove(this);
             PlatformImpl.Dispose();
+            IsVisible = false;
         }
 
         protected override void HandleApplicationExiting()
@@ -215,22 +217,25 @@ namespace Avalonia.Controls
         /// <summary>
         /// Hides the window but does not close it.
         /// </summary>
-        public void Hide()
+        public override void Hide()
         {
             using (BeginAutoSizing())
             {
                 PlatformImpl.Hide();
             }
+
+            IsVisible = false;
         }
 
         /// <summary>
         /// Shows the window.
         /// </summary>
-        public void Show()
+        public override void Show()
         {
             s_windows.Add(this);
 
             EnsureInitialized();
+            IsVisible = true;
             LayoutManager.Instance.ExecuteInitialLayoutPass(this);
 
             using (BeginAutoSizing())
@@ -264,18 +269,27 @@ namespace Avalonia.Controls
             s_windows.Add(this);
 
             EnsureInitialized();
+            IsVisible = true;
             LayoutManager.Instance.ExecuteInitialLayoutPass(this);
 
             using (BeginAutoSizing())
             {
+                var affectedWindows = s_windows.Where(w => w.IsEnabled && w != this).ToList();
+                var activated = affectedWindows.Where(w => w.IsActive).FirstOrDefault();
+                SetIsEnabled(affectedWindows, false);
+
                 var modal = PlatformImpl.ShowDialog();
                 var result = new TaskCompletionSource<TResult>();
 
-                Observable.FromEventPattern(this, nameof(Closed))
+                Observable.FromEventPattern<EventHandler, EventArgs>(
+                    x => this.Closed += x,
+                    x => this.Closed -= x)
                     .Take(1)
                     .Subscribe(_ =>
                     {
                         modal.Dispose();
+                        SetIsEnabled(affectedWindows, true);
+                        activated?.Activate();
                         result.SetResult((TResult)_dialogResult);
                     });
 
@@ -283,6 +297,14 @@ namespace Avalonia.Controls
             }
         }
 
+        void SetIsEnabled(IEnumerable<Window> windows, bool isEnabled)
+        {
+            foreach (var window in windows)
+            {
+                window.IsEnabled = isEnabled;
+            }
+        }
+
         /// <inheritdoc/>
         void INameScope.Register(string name, object element)
         {
@@ -329,6 +351,12 @@ namespace Avalonia.Controls
             return size;
         }
 
+        protected override void HandleClosed()
+        {
+            IsVisible = false;
+            base.HandleClosed();
+        }
+
         /// <inheritdoc/>
         protected override void HandleResized(Size clientSize)
         {
@@ -339,16 +367,6 @@ namespace Avalonia.Controls
 
             base.HandleResized(clientSize);
         }
-
-        private void EnsureInitialized()
-        {
-            if (!this.IsInitialized)
-            {
-                var init = (ISupportInitialize)this;
-                init.BeginInit();
-                init.EndInit();
-            }
-        }
     }
 }
 

+ 88 - 3
src/Avalonia.Controls/WindowBase.cs

@@ -29,6 +29,13 @@ namespace Avalonia.Controls
             AvaloniaProperty.RegisterDirect<WindowBase, bool>(nameof(IsActive), o => o.IsActive);
 
         private bool _isActive;
+        private bool _ignoreVisibilityChange;
+
+        static WindowBase()
+        {
+            IsVisibleProperty.OverrideDefaultValue<WindowBase>(false);
+            IsVisibleProperty.Changed.AddClassHandler<WindowBase>(x => x.IsVisibleChanged);
+        }
 
         public WindowBase(IWindowBaseImpl impl) : this(impl, AvaloniaLocator.Current)
         {
@@ -59,7 +66,6 @@ namespace Avalonia.Controls
 
         public new IWindowBaseImpl PlatformImpl => (IWindowBaseImpl) base.PlatformImpl;
 
-
         /// <summary>
         /// Gets a value that indicates whether the window is active.
         /// </summary>
@@ -95,6 +101,43 @@ namespace Avalonia.Controls
             PlatformImpl.Activate();
         }
 
+        /// <summary>
+        /// Hides the popup.
+        /// </summary>
+        public virtual void Hide()
+        {
+            _ignoreVisibilityChange = true;
+
+            try
+            {
+                PlatformImpl.Hide();
+                IsVisible = false;
+            }
+            finally
+            {
+                _ignoreVisibilityChange = false;
+            }
+        }
+
+        /// <summary>
+        /// Shows the popup.
+        /// </summary>
+        public virtual void Show()
+        {
+            _ignoreVisibilityChange = true;
+
+            try
+            {
+                EnsureInitialized();
+                IsVisible = true;
+                LayoutManager.Instance.ExecuteInitialLayoutPass(this);
+                PlatformImpl.Show();
+            }
+            finally
+            {
+                _ignoreVisibilityChange = false;
+            }
+        }
 
         /// <summary>
         /// Begins an auto-resize operation.
@@ -126,6 +169,34 @@ namespace Avalonia.Controls
             return base.ArrangeOverride(PlatformImpl.ClientSize);
         }
 
+        /// <summary>
+        /// Ensures that the window is initialized.
+        /// </summary>
+        protected void EnsureInitialized()
+        {
+            if (!this.IsInitialized)
+            {
+                var init = (ISupportInitialize)this;
+                init.BeginInit();
+                init.EndInit();
+            }
+        }
+
+        protected override void HandleClosed()
+        {
+            _ignoreVisibilityChange = true;
+
+            try
+            {
+                IsVisible = false;
+                base.HandleClosed();
+            }
+            finally
+            {
+                _ignoreVisibilityChange = false;
+            }
+        }
+
         /// <summary>
         /// Handles a resize notification from <see cref="ITopLevelImpl.Resized"/>.
         /// </summary>
@@ -139,8 +210,7 @@ namespace Avalonia.Controls
             }
             ClientSize = clientSize;
             LayoutManager.Instance.ExecuteLayoutPass();
-            PlatformImpl.Invalidate(new Rect(clientSize));
-
+            Renderer?.Resized(clientSize);
         }
 
         /// <summary>
@@ -180,6 +250,21 @@ namespace Avalonia.Controls
             Deactivated?.Invoke(this, EventArgs.Empty);
         }
 
+        private void IsVisibleChanged(AvaloniaPropertyChangedEventArgs e)
+        {
+            if (!_ignoreVisibilityChange)
+            {
+                if ((bool)e.NewValue)
+                {
+                    Show();
+                }
+                else
+                {
+                    Hide();
+                }
+            }
+        }
+
         /// <summary>
         /// Starts moving a window with left button being held. Should be called from left mouse button press event handler
         /// </summary>

+ 0 - 9
src/Avalonia.Controls/packages.config

@@ -1,9 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="JetBrains.Annotations" version="10.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Core" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Linq" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.PlatformServices" version="3.0.0" targetFramework="portable45-net45+win8" />
-</packages>

+ 16 - 95
src/Avalonia.DesignerSupport/Avalonia.DesignerSupport.csproj

@@ -1,22 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{799A7BB5-3C2C-48B6-85A7-406A12C420DA}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avalonia</RootNamespace>
-    <AssemblyName>Avalonia.DesignerSupport</AssemblyName>
-    <DefaultLanguage>en-US</DefaultLanguage>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>
-    </NuGetPackageImportStamp>
+    <TargetFramework>netstandard1.1</TargetFramework>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
     <DebugSymbols>true</DebugSymbols>
@@ -40,87 +25,23 @@
     <NoWarn>CS1591</NoWarn>
   </PropertyGroup>
   <ItemGroup>
-    <!-- A reference to the entire .NET Framework is automatically included -->
-    <ProjectReference Include="..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
-      <Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project>
-      <Name>Avalonia.Markup.Xaml</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
-      <Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
-      <Name>Avalonia.Markup</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj">
-      <Project>{d211e587-d8bc-45b9-95a4-f297c8fa5200}</Project>
-      <Name>Avalonia.Animation</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj">
-      <Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
-      <Name>Avalonia.Base</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj">
-      <Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
-      <Name>Avalonia.Controls</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Input\Avalonia.Input.csproj">
-      <Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
-      <Name>Avalonia.Input</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
-      <Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
-      <Name>Avalonia.Interactivity</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Layout\Avalonia.Layout.csproj">
-      <Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
-      <Name>Avalonia.Layout</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Visuals\Avalonia.Visuals.csproj">
-      <Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
-      <Name>Avalonia.Visuals</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Styling\Avalonia.Styling.csproj">
-      <Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
-      <Name>Avalonia.Styling</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj">
-      <Project>{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}</Project>
-      <Name>Avalonia.Themes.Default</Name>
-    </ProjectReference>
+    <ProjectReference Include="..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />
+    <ProjectReference Include="..\Markup\Avalonia.Markup\Avalonia.Markup.csproj" />
+    <ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj" />
+    <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
+    <ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj" />
+    <ProjectReference Include="..\Avalonia.Input\Avalonia.Input.csproj" />
+    <ProjectReference Include="..\Avalonia.Interactivity\Avalonia.Interactivity.csproj" />
+    <ProjectReference Include="..\Avalonia.Layout\Avalonia.Layout.csproj" />
+    <ProjectReference Include="..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
+    <ProjectReference Include="..\Avalonia.Styling\Avalonia.Styling.csproj" />
+    <ProjectReference Include="..\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Shared\SharedAssemblyInfo.cs">
       <Link>Properties\SharedAssemblyInfo.cs</Link>
     </Compile>
-    <Compile Include="DesignerAssist.cs" />
-    <Compile Include="DesignerApi.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
   </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Core.3.0.0\lib\netstandard1.1\System.Reactive.Core.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Interfaces.3.0.0\lib\netstandard1.0\System.Reactive.Interfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Linq, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Linq.3.0.0\lib\netstandard1.1\System.Reactive.Linq.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.PlatformServices, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\netstandard1.0\System.Reactive.PlatformServices.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-  </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Microsoft.CSharp.props" />
+  <Import Project="..\..\build\Rx.props" />
 </Project>

+ 0 - 8
src/Avalonia.DesignerSupport/packages.config

@@ -1,8 +0,0 @@
-<?xml version="1.0" encoding="utf-8"?>
-<packages>
-  <package id="System.Reactive" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Core" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Interfaces" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.Linq" version="3.0.0" targetFramework="portable45-net45+win8" />
-  <package id="System.Reactive.PlatformServices" version="3.0.0" targetFramework="portable45-net45+win8" />
-</packages>

+ 20 - 122
src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj

@@ -1,22 +1,7 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
+<Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <MinimumVisualStudioVersion>11.0</MinimumVisualStudioVersion>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProjectGuid>{7062AE20-5DCC-4442-9645-8195BDECE63E}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Avalonia.Diagnostics</RootNamespace>
-    <AssemblyName>Avalonia.Diagnostics</AssemblyName>
-    <DefaultLanguage>en-US</DefaultLanguage>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{786C830F-07A1-408B-BD7F-6EE04809D6DB};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <TargetFrameworkProfile>Profile7</TargetFrameworkProfile>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <NuGetPackageImportStamp>
-    </NuGetPackageImportStamp>
+    <TargetFramework>netstandard1.1</TargetFramework>
+    <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
     <DebugSymbols>true</DebugSymbols>
@@ -41,117 +26,30 @@
     <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
   </PropertyGroup>
   <ItemGroup>
-    <!-- A reference to the entire .NET Framework is automatically included -->
-    <ProjectReference Include="..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
-      <Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project>
-      <Name>Avalonia.Markup.Xaml</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
-      <Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
-      <Name>Avalonia.Markup</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj">
-      <Project>{D211E587-D8BC-45B9-95A4-F297C8FA5200}</Project>
-      <Name>Avalonia.Animation</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj">
-      <Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
-      <Name>Avalonia.Base</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj">
-      <Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
-      <Name>Avalonia.Controls</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Input\Avalonia.Input.csproj">
-      <Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
-      <Name>Avalonia.Input</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
-      <Project>{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}</Project>
-      <Name>Avalonia.Interactivity</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Layout\Avalonia.Layout.csproj">
-      <Project>{42472427-4774-4C81-8AFF-9F27B8E31721}</Project>
-      <Name>Avalonia.Layout</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj">
-      <Project>{6417B24E-49C2-4985-8DB2-3AB9D898EC91}</Project>
-      <Name>Avalonia.ReactiveUI</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Visuals\Avalonia.Visuals.csproj">
-      <Project>{EB582467-6ABB-43A1-B052-E981BA910E3A}</Project>
-      <Name>Avalonia.Visuals</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Styling\Avalonia.Styling.csproj">
-      <Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
-      <Name>Avalonia.Styling</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj">
-      <Project>{3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f}</Project>
-      <Name>Avalonia.Themes.Default</Name>
-    </ProjectReference>
+    <ProjectReference Include="..\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />
+    <ProjectReference Include="..\Markup\Avalonia.Markup\Avalonia.Markup.csproj" />
+    <ProjectReference Include="..\Avalonia.Animation\Avalonia.Animation.csproj" />
+    <ProjectReference Include="..\Avalonia.Base\Avalonia.Base.csproj" />
+    <ProjectReference Include="..\Avalonia.Controls\Avalonia.Controls.csproj" />
+    <ProjectReference Include="..\Avalonia.Input\Avalonia.Input.csproj" />
+    <ProjectReference Include="..\Avalonia.Interactivity\Avalonia.Interactivity.csproj" />
+    <ProjectReference Include="..\Avalonia.Layout\Avalonia.Layout.csproj" />
+    <ProjectReference Include="..\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj" />
+    <ProjectReference Include="..\Avalonia.Visuals\Avalonia.Visuals.csproj" />
+    <ProjectReference Include="..\Avalonia.Styling\Avalonia.Styling.csproj" />
+    <ProjectReference Include="..\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
   </ItemGroup>
   <ItemGroup>
     <Compile Include="..\Shared\SharedAssemblyInfo.cs">
       <Link>Properties\SharedAssemblyInfo.cs</Link>
     </Compile>
-    <Compile Include="LogManager.cs" />
-    <Compile Include="Debug.cs" />
-    <Compile Include="Properties\AssemblyInfo.cs" />
-    <Compile Include="ViewLocator.cs" />
-    <Compile Include="ViewModels\DevToolsViewModel.cs" />
-    <Compile Include="ViewModels\TreePageViewModel.cs" />
-    <Compile Include="ViewModels\PropertyDetails.cs" />
-    <Compile Include="ViewModels\ControlDetailsViewModel.cs" />
-    <Compile Include="ViewModels\LogicalTreeNode.cs" />
-    <Compile Include="ViewModels\TreeNode.cs" />
-    <Compile Include="ViewModels\VisualTreeNode.cs" />
-    <Compile Include="Views\SimpleGrid.cs" />
-    <Compile Include="Views\TreePage.xaml.cs">
-      <DependentUpon>TreePageView.xaml</DependentUpon>
+    <Compile Update="**\*.xaml.cs">
+      <DependentUpon>%(Filename)</DependentUpon>
     </Compile>
-    <Compile Include="DevTools.xaml.cs">
-      <DependentUpon>DevTools.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="Views\ControlDetailsView.cs" />
-    <Compile Include="Views\GridRepeater.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Reference Include="Splat">
-      <HintPath>..\..\packages\Splat.1.6.2\lib\Portable-net45+win+wpa81+wp80\Splat.dll</HintPath>
-    </Reference>
-    <Reference Include="System.Reactive.Core, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Core.3.0.0\lib\netstandard1.1\System.Reactive.Core.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Interfaces, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Interfaces.3.0.0\lib\netstandard1.0\System.Reactive.Interfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.Linq, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.Linq.3.0.0\lib\netstandard1.1\System.Reactive.Linq.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="System.Reactive.PlatformServices, Version=3.0.0.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
-      <HintPath>..\..\packages\System.Reactive.PlatformServices.3.0.0\lib\netstandard1.0\System.Reactive.PlatformServices.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="packages.config" />
-    <EmbeddedResource Include="DevTools.xaml">
-      <SubType>Designer</SubType>
-    </EmbeddedResource>
-    <EmbeddedResource Include="Views\TreePageView.xaml">
+    <EmbeddedResource Include="**\*.xaml">
       <SubType>Designer</SubType>
     </EmbeddedResource>
   </ItemGroup>
-  <Import Project="$(MSBuildExtensionsPath32)\Microsoft\Portable\$(TargetFrameworkVersion)\Microsoft.Portable.CSharp.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+  <Import Project="..\..\build\Rx.props" />
+  <Import Project="..\..\build\Splat.props" />
 </Project>

+ 5 - 5
src/Avalonia.Diagnostics/ViewModels/ControlDetailsViewModel.cs

@@ -3,19 +3,19 @@
 
 using System.Collections.Generic;
 using System.Linq;
-using Avalonia.Controls;
+using Avalonia.VisualTree;
 using ReactiveUI;
 
 namespace Avalonia.Diagnostics.ViewModels
 {
     internal class ControlDetailsViewModel : ReactiveObject
     {
-        public ControlDetailsViewModel(Control control)
+        public ControlDetailsViewModel(IVisual control)
         {
-            if (control != null)
+            if (control is AvaloniaObject avaloniaObject)
             {
-                Properties = AvaloniaPropertyRegistry.Instance.GetRegistered(control)
-                    .Select(x => new PropertyDetails(control, x))
+                Properties = AvaloniaPropertyRegistry.Instance.GetRegistered(avaloniaObject)
+                    .Select(x => new PropertyDetails(avaloniaObject, x))
                     .OrderBy(x => x.IsAttached)
                     .ThenBy(x => x.Name);
             }

+ 26 - 23
src/Avalonia.Diagnostics/ViewModels/TreeNode.cs

@@ -5,8 +5,8 @@ using System;
 using System.Collections.Specialized;
 using System.Reactive;
 using System.Reactive.Linq;
-using Avalonia.Controls;
 using Avalonia.Styling;
+using Avalonia.VisualTree;
 using ReactiveUI;
 
 namespace Avalonia.Diagnostics.ViewModels
@@ -16,32 +16,35 @@ namespace Avalonia.Diagnostics.ViewModels
         private string _classes;
         private bool _isExpanded;
 
-        public TreeNode(Control control, TreeNode parent)
+        public TreeNode(IVisual visual, TreeNode parent)
         {
-            Control = control;
             Parent = parent;
-            Type = control.GetType().Name;
+            Type = visual.GetType().Name;
+            Visual = visual;
 
-            var classesChanged = Observable.FromEventPattern<
-                    NotifyCollectionChangedEventHandler, 
-                    NotifyCollectionChangedEventArgs>(
-                x => control.Classes.CollectionChanged += x,
-                x => control.Classes.CollectionChanged -= x)
-                .TakeUntil(((IStyleable)control).StyleDetach);
+            if (visual is IStyleable styleable)
+            {
+                var classesChanged = Observable.FromEventPattern<
+                        NotifyCollectionChangedEventHandler,
+                        NotifyCollectionChangedEventArgs>(
+                    x => styleable.Classes.CollectionChanged += x,
+                    x => styleable.Classes.CollectionChanged -= x)
+                    .TakeUntil(((IStyleable)styleable).StyleDetach);
 
-            classesChanged.Select(_ => Unit.Default)
-                .StartWith(Unit.Default)
-                .Subscribe(_ =>
-                {
-                    if (control.Classes.Count > 0)
+                classesChanged.Select(_ => Unit.Default)
+                    .StartWith(Unit.Default)
+                    .Subscribe(_ =>
                     {
-                        Classes = "(" + string.Join(" ", control.Classes) + ")";
-                    }
-                    else
-                    {
-                        Classes = string.Empty;
-                    }
-                });
+                        if (styleable.Classes.Count > 0)
+                        {
+                            Classes = "(" + string.Join(" ", styleable.Classes) + ")";
+                        }
+                        else
+                        {
+                            Classes = string.Empty;
+                        }
+                    });
+            }
         }
 
         public IReadOnlyReactiveList<TreeNode> Children
@@ -56,7 +59,7 @@ namespace Avalonia.Diagnostics.ViewModels
             private set { this.RaiseAndSetIfChanged(ref _classes, value); }
         }
 
-        public Control Control
+        public IVisual Visual
         {
             get;
         }

Энэ ялгаанд хэт олон файл өөрчлөгдсөн тул зарим файлыг харуулаагүй болно