Преглед изворни кода

Merge remote-tracking branch 'upstream/master' into monomac

Nikita Tsukanov пре 8 година
родитељ
комит
8c7d41dd9e
100 измењених фајлова са 1394 додато и 881 уклоњено
  1. 9 2
      .gitignore
  2. 5 7
      .gitmodules
  3. 1 0
      .ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject
  4. 1 3
      .ncrunch/Avalonia.DotNetCoreRuntime.v3.ncrunchproject
  5. 1 3
      .ncrunch/Avalonia.Gtk3.v3.ncrunchproject
  6. 5 0
      .ncrunch/Avalonia.LinuxFramebuffer.v3.ncrunchproject
  7. 9 0
      .ncrunch/Avalonia.Markup.UnitTests.netcoreapp1.1.v3.ncrunchproject
  8. 1 0
      .ncrunch/Avalonia.Skia.RenderTests.v3.ncrunchproject
  9. 5 0
      .ncrunch/Avalonia.Visuals.UnitTests.net461.v3.ncrunchproject
  10. 5 0
      .ncrunch/Avalonia.Win32.Interop.v3.ncrunchproject
  11. 1 3
      .ncrunch/Avalonia.Win32.NetStandard.v3.ncrunchproject
  12. 5 0
      .ncrunch/ControlCatalog.NetCore.v3.ncrunchproject
  13. 2 1
      .travis.yml
  14. 121 199
      Avalonia.sln
  15. 3 4
      appveyor.yml
  16. 72 54
      build.cake
  17. 5 0
      build/Base.props
  18. 1 1
      build/Magick.NET-Q16-AnyCPU.props
  19. 5 0
      build/Markup.props
  20. 1 1
      build/Moq.props
  21. 5 4
      build/SharpDX.props
  22. 1 1
      build/SkiaSharp.props
  23. 0 20
      build/UnitTests.NetCore.targets
  24. 16 2
      build/XUnit.props
  25. 7 6
      docs/guidelines/build.md
  26. 2 2
      docs/tutorial/from-wpf.md
  27. 100 91
      packages.cake
  28. 2 32
      parameters.cake
  29. 3 3
      readme.md
  30. 8 8
      samples/BindingTest/App.config
  31. 2 2
      samples/BindingTest/BindingTest.csproj
  32. 4 1
      samples/BindingTest/MainWindow.xaml
  33. 12 0
      samples/BindingTest/ViewModels/MainWindowViewModel.cs
  34. 20 0
      samples/BindingTest/ViewModels/NestedCommandViewModel.cs
  35. 3 4
      samples/ControlCatalog.Android/ControlCatalog.Android.csproj
  36. 8 8
      samples/ControlCatalog.Desktop/App.config
  37. 4 5
      samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
  38. 1 1
      samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
  39. 3 4
      samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj
  40. 9 2
      samples/ControlCatalog/ControlCatalog.csproj
  41. 1 0
      samples/ControlCatalog/MainView.xaml
  42. 3 1
      samples/ControlCatalog/MainWindow.xaml.cs
  43. 36 0
      samples/ControlCatalog/Pages/ContextMenuPage.xaml
  44. 18 0
      samples/ControlCatalog/Pages/ContextMenuPage.xaml.cs
  45. 25 25
      samples/ControlCatalog/Pages/MenuPage.xaml
  46. 36 17
      samples/ControlCatalog/Pages/ToolTipPage.xaml
  47. 8 8
      samples/RenderTest/App.config
  48. 1 0
      samples/RenderTest/MainWindow.xaml
  49. 132 0
      samples/RenderTest/Pages/DrawingPage.xaml
  50. 18 0
      samples/RenderTest/Pages/DrawingPage.xaml.cs
  51. 12 5
      samples/RenderTest/RenderTest.csproj
  52. 8 8
      samples/VirtualizationTest/App.config
  53. 1 2
      samples/VirtualizationTest/VirtualizationTest.csproj
  54. 3 3
      samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj
  55. 1 1
      samples/interop/Direct3DInteropSample/Program.cs
  56. 4 5
      samples/interop/GtkInteropDemo/GtkInteropDemo.csproj
  57. 13 1
      samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml
  58. 14 1
      samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml.cs
  59. 1 1
      samples/interop/WindowsInteropTest/Program.cs
  60. 10 6
      samples/interop/WindowsInteropTest/WindowsInteropTest.csproj
  61. 5 0
      scripts/ReplaceNugetCache.ps1
  62. 7 0
      scripts/ReplaceNugetCache.sh
  63. 5 0
      scripts/ReplaceNugetCacheRelease.ps1
  64. 0 3
      src/Android/Avalonia.Android/AndroidPlatform.cs
  65. 3 7
      src/Android/Avalonia.Android/Avalonia.Android.csproj
  66. 2 0
      src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs
  67. 1 1
      src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs
  68. 10 1
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  69. 1 1
      src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs
  70. 3 4
      src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj
  71. 1 1
      src/Avalonia.Animation/Avalonia.Animation.csproj
  72. 3 1
      src/Avalonia.Base/Avalonia.Base.csproj
  73. 3 16
      src/Avalonia.Base/AvaloniaObject.cs
  74. 3 0
      src/Avalonia.Base/AvaloniaPropertyRegistry.cs
  75. 34 20
      src/Avalonia.Base/Collections/AvaloniaDictionary.cs
  76. 1 1
      src/Avalonia.Base/Collections/AvaloniaList.cs
  77. 33 90
      src/Avalonia.Base/Collections/AvaloniaListExtensions.cs
  78. 9 30
      src/Avalonia.Base/Data/BindingNotification.cs
  79. 53 0
      src/Avalonia.Base/Logging/LoggerExtensions.cs
  80. 15 0
      src/Avalonia.Base/Metadata/AmbientAttribute.cs
  81. 15 0
      src/Avalonia.Base/Metadata/TemplateContent.cs
  82. 1 1
      src/Avalonia.Base/PriorityBindingEntry.cs
  83. 1 8
      src/Avalonia.Base/PriorityValue.cs
  84. 0 23
      src/Avalonia.Base/Utilities/ExceptionUtilities.cs
  85. 3 2
      src/Avalonia.Base/Utilities/WeakObservable.cs
  86. 12 12
      src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs
  87. 57 9
      src/Avalonia.Controls/Application.cs
  88. 1 1
      src/Avalonia.Controls/Avalonia.Controls.csproj
  89. 42 16
      src/Avalonia.Controls/Button.cs
  90. 14 0
      src/Avalonia.Controls/Classes.cs
  91. 1 1
      src/Avalonia.Controls/ContextMenu.cs
  92. 148 52
      src/Avalonia.Controls/Control.cs
  93. 59 0
      src/Avalonia.Controls/DrawingPresenter.cs
  94. 1 1
      src/Avalonia.Controls/DropDown.cs
  95. 6 4
      src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs
  96. 9 6
      src/Avalonia.Controls/IControl.cs
  97. 1 5
      src/Avalonia.Controls/IGlobalDataTemplates.cs
  98. 1 1
      src/Avalonia.Controls/Menu.cs
  99. 11 2
      src/Avalonia.Controls/MenuItem.cs
  100. 6 3
      src/Avalonia.Controls/Panel.cs

+ 9 - 2
.gitignore

@@ -108,7 +108,7 @@ AppPackages/
 # NCrunch
 _NCrunch_*/
 *.ncrunchsolution.user
-nCrunchTemp_*/
+nCrunchTemp_*
 
 # Others
 sql/
@@ -159,10 +159,17 @@ $RECYCLE.BIN/
 *.userprefs
 *.nugetreferenceswitcher
 
+
+#################
+## Rider
+#################
+.idea
+
 #################
 ## Cake
 #################
-tools/
+tools/*
+!tools/packages.config
 .nuget
 artifacts/
 nuget

+ 5 - 7
.gitmodules

@@ -1,13 +1,11 @@
 [submodule "src/Avalonia.ReactiveUI/src"]
 	path = src/Avalonia.ReactiveUI/src
-	url = https://github.com/reactiveui/ReactiveUI.git
+	url = https://github.com/AvaloniaUI/ReactiveUI.git
+	branch = avalonia-snapshot
 [submodule "src/Avalonia.HtmlRenderer/external"]
 	path = src/Avalonia.HtmlRenderer/external
 	url = https://github.com/AvaloniaUI/HTML-Renderer.git
 	branch = perspex-pcl
-[submodule "src/Markup/Avalonia.Markup.Xaml/OmniXAML"]
-	path = src/Markup/Avalonia.Markup.Xaml/OmniXAML
-	url = https://github.com/AvaloniaUI/OmniXAML.git
-[submodule "src/Markup/Avalonia.Markup.Xaml/glass"]
-	path = src/Markup/Avalonia.Markup.Xaml/glass
-	url = https://github.com/SuperJMN/glass
+[submodule "src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github"]
+	path = src/Markup/Avalonia.Markup.Xaml/PortableXaml/portable.xaml.github
+	url = https://github.com/AvaloniaUI/Portable.Xaml.git

+ 1 - 0
.ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject

@@ -1,6 +1,7 @@
 <ProjectConfiguration>
   <Settings>
     <DefaultTestTimeout>1000</DefaultTestTimeout>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
     <PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
   </Settings>
 </ProjectConfiguration>

+ 1 - 3
.ncrunch/Avalonia.DotNetCoreRuntime.v3.ncrunchproject

@@ -1,5 +1,3 @@
 <ProjectConfiguration>
-  <Settings>
-    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
-  </Settings>
+  <Settings />
 </ProjectConfiguration>

+ 1 - 3
.ncrunch/Avalonia.Gtk3.v3.ncrunchproject

@@ -1,5 +1,3 @@
 <ProjectConfiguration>
-  <Settings>
-    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
-  </Settings>
+  <Settings />
 </ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.LinuxFramebuffer.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
+  </Settings>
+</ProjectConfiguration>

+ 9 - 0
.ncrunch/Avalonia.Markup.UnitTests.netcoreapp1.1.v3.ncrunchproject

@@ -0,0 +1,9 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoredTests>
+      <NamedTestSelector>
+        <TestName>Avalonia.Markup.UnitTests.Data.Plugins.DataAnnotationsValidationPluginTests.Produces_Aggregate_BindingNotificationsx</TestName>
+      </NamedTestSelector>
+    </IgnoredTests>
+  </Settings>
+</ProjectConfiguration>

+ 1 - 0
.ncrunch/Avalonia.Skia.RenderTests.v3.ncrunchproject

@@ -1,6 +1,7 @@
 <ProjectConfiguration>
   <Settings>
     <DefaultTestTimeout>1000</DefaultTestTimeout>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
     <PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
   </Settings>
 </ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.Visuals.UnitTests.net461.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
+  </Settings>
+</ProjectConfiguration>

+ 5 - 0
.ncrunch/Avalonia.Win32.Interop.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
+  </Settings>
+</ProjectConfiguration>

+ 1 - 3
.ncrunch/Avalonia.Win32.NetStandard.v3.ncrunchproject

@@ -1,5 +1,3 @@
 <ProjectConfiguration>
-  <Settings>
-    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
-  </Settings>
+  <Settings />
 </ProjectConfiguration>

+ 5 - 0
.ncrunch/ControlCatalog.NetCore.v3.ncrunchproject

@@ -0,0 +1,5 @@
+<ProjectConfiguration>
+  <Settings>
+    <IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely>
+  </Settings>
+</ProjectConfiguration>

+ 2 - 1
.travis.yml

@@ -3,13 +3,14 @@ os:
   - linux
   - osx
 dist: trusty
+osx_image: xcode8.3
 env:
   global:
     - DOTNET_SKIP_FIRST_TIME_EXPERIENCE=1
     - DOTNET_CLI_TELEMETRY_OPTOUT=1
 mono:
   - latest
-dotnet: 1.0.1
+dotnet: 2.0.0
 script:
   - ./build.sh --target "Travis" --platform "Mono" --configuration "Release"
 notifications:

+ 121 - 199
Avalonia.sln

@@ -2,61 +2,61 @@ Microsoft Visual Studio Solution File, Format Version 12.00
 # 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}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Base", "src\Avalonia.Base\Avalonia.Base.csproj", "{B09B78D8-9B26-48B0-9149-D64A2F120F3F}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Visuals", "src\Avalonia.Visuals\Avalonia.Visuals.csproj", "{EB582467-6ABB-43A1-B052-E981BA910E3A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Visuals", "src\Avalonia.Visuals\Avalonia.Visuals.csproj", "{EB582467-6ABB-43A1-B052-E981BA910E3A}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Layout", "src\Avalonia.Layout\Avalonia.Layout.csproj", "{42472427-4774-4C81-8AFF-9F27B8E31721}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Layout", "src\Avalonia.Layout\Avalonia.Layout.csproj", "{42472427-4774-4C81-8AFF-9F27B8E31721}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Windows", "Windows", "{B39A8919-9F95-48FE-AD7B-76E08B509888}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Win32", "src\Windows\Avalonia.Win32\Avalonia.Win32.csproj", "{811A76CF-1CF6-440F-963B-BBE31BD72A82}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Direct2D1", "src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj", "{3E908F67-5543-4879-A1DC-08EACE79B3CD}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Input", "src\Avalonia.Input\Avalonia.Input.csproj", "{62024B2D-53EB-4638-B26B-85EEAA54866E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Input", "src\Avalonia.Input\Avalonia.Input.csproj", "{62024B2D-53EB-4638-B26B-85EEAA54866E}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Interactivity", "src\Avalonia.Interactivity\Avalonia.Interactivity.csproj", "{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Interactivity", "src\Avalonia.Interactivity\Avalonia.Interactivity.csproj", "{6B0ED19D-A08B-461C-A9D9-A9EE40B0C06B}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Controls", "src\Avalonia.Controls\Avalonia.Controls.csproj", "{D2221C82-4A25-4583-9B43-D791E3F6820C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls", "src\Avalonia.Controls\Avalonia.Controls.csproj", "{D2221C82-4A25-4583-9B43-D791E3F6820C}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Styling", "src\Avalonia.Styling\Avalonia.Styling.csproj", "{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Styling", "src\Avalonia.Styling\Avalonia.Styling.csproj", "{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Themes.Default", "src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Themes.Default", "src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj", "{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Diagnostics", "src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Diagnostics", "src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj", "{7062AE20-5DCC-4442-9645-8195BDECE63E}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Animation", "src\Avalonia.Animation\Avalonia.Animation.csproj", "{D211E587-D8BC-45B9-95A4-F297C8FA5200}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Animation", "src\Avalonia.Animation\Avalonia.Animation.csproj", "{D211E587-D8BC-45B9-95A4-F297C8FA5200}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Tests", "Tests", "{C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Styling.UnitTests", "tests\Avalonia.Styling.UnitTests\Avalonia.Styling.UnitTests.csproj", "{47ECDF59-DEF8-4C53-87B1-2098A3429059}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Styling.UnitTests", "tests\Avalonia.Styling.UnitTests\Avalonia.Styling.UnitTests.csproj", "{47ECDF59-DEF8-4C53-87B1-2098A3429059}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Controls.UnitTests", "tests\Avalonia.Controls.UnitTests\Avalonia.Controls.UnitTests.csproj", "{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Controls.UnitTests", "tests\Avalonia.Controls.UnitTests\Avalonia.Controls.UnitTests.csproj", "{5CCB5571-7C30-4E7D-967D-0E2158EBD91F}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Visuals.UnitTests", "tests\Avalonia.Visuals.UnitTests\Avalonia.Visuals.UnitTests.csproj", "{76716382-3159-460E-BDA6-C5715CF606D7}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Visuals.UnitTests", "tests\Avalonia.Visuals.UnitTests\Avalonia.Visuals.UnitTests.csproj", "{76716382-3159-460E-BDA6-C5715CF606D7}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Base.UnitTests", "tests\Avalonia.Base.UnitTests\Avalonia.Base.UnitTests.csproj", "{2905FF23-53FB-45E6-AA49-6AF47A172056}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Base.UnitTests", "tests\Avalonia.Base.UnitTests\Avalonia.Base.UnitTests.csproj", "{2905FF23-53FB-45E6-AA49-6AF47A172056}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Layout.UnitTests", "tests\Avalonia.Layout.UnitTests\Avalonia.Layout.UnitTests.csproj", "{DB070A10-BF39-4752-8456-86E9D5928478}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Layout.UnitTests", "tests\Avalonia.Layout.UnitTests\Avalonia.Layout.UnitTests.csproj", "{DB070A10-BF39-4752-8456-86E9D5928478}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Interactivity.UnitTests", "tests\Avalonia.Interactivity.UnitTests\Avalonia.Interactivity.UnitTests.csproj", "{08478EF5-44E8-42E9-92D6-15E00EC038D8}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Interactivity.UnitTests", "tests\Avalonia.Interactivity.UnitTests\Avalonia.Interactivity.UnitTests.csproj", "{08478EF5-44E8-42E9-92D6-15E00EC038D8}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Direct2D1.RenderTests", "tests\Avalonia.RenderTests\Avalonia.Direct2D1.RenderTests.csproj", "{DABFD304-D6A4-4752-8123-C2CCF7AC7831}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Input.UnitTests", "tests\Avalonia.Input.UnitTests\Avalonia.Input.UnitTests.csproj", "{AC18926A-E784-40FE-B09D-BB0FE2B599F0}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Input.UnitTests", "tests\Avalonia.Input.UnitTests\Avalonia.Input.UnitTests.csproj", "{AC18926A-E784-40FE-B09D-BB0FE2B599F0}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Direct2D1.UnitTests", "tests\Avalonia.Direct2D1.UnitTests\Avalonia.Direct2D1.UnitTests.csproj", "{EFB11458-9CDF-41C0-BE4F-44AF45A4CAB8}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Cairo.RenderTests", "tests\Avalonia.RenderTests\Avalonia.Cairo.RenderTests.csproj", "{E106CF37-4066-4615-B684-172A6D30B058}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Markup.Xaml.UnitTests", "tests\Avalonia.Markup.Xaml.UnitTests\Avalonia.Markup.Xaml.UnitTests.csproj", "{99135EAB-653D-47E4-A378-C96E1278CA44}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.Xaml.UnitTests", "tests\Avalonia.Markup.Xaml.UnitTests\Avalonia.Markup.Xaml.UnitTests.csproj", "{99135EAB-653D-47E4-A378-C96E1278CA44}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Markup", "Markup", "{8B6A8209-894F-4BA1-B880-965FD453982C}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Markup.Xaml", "src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj", "{3E53A01A-B331-47F3-B828-4A5717E77A24}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.Xaml", "src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj", "{3E53A01A-B331-47F3-B828-4A5717E77A24}"
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Samples", "Samples", "{9B9E3891-2366-4253-A952-D08BCEB71098}"
 EndProject
@@ -71,15 +71,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Gtk", "src\Gtk\Ava
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Cairo", "src\Gtk\Avalonia.Cairo\Avalonia.Cairo.csproj", "{FB05AC90-89BA-4F2F-A924-F37875FB547C}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.ReactiveUI", "src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj", "{6417B24E-49C2-4985-8DB2-3AB9D898EC91}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.ReactiveUI", "src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj", "{6417B24E-49C2-4985-8DB2-3AB9D898EC91}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.HtmlRenderer", "src\Avalonia.HtmlRenderer\Avalonia.HtmlRenderer.csproj", "{5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.HtmlRenderer", "src\Avalonia.HtmlRenderer\Avalonia.HtmlRenderer.csproj", "{5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}"
 EndProject
 Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "PlatformSupport", "src\Shared\PlatformSupport\PlatformSupport.shproj", "{E4D9629C-F168-4224-3F51-A5E482FFBC42}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Markup", "src\Markup\Avalonia.Markup\Avalonia.Markup.csproj", "{6417E941-21BC-467B-A771-0DE389353CE6}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup", "src\Markup\Avalonia.Markup\Avalonia.Markup.csproj", "{6417E941-21BC-467B-A771-0DE389353CE6}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Markup.UnitTests", "tests\Avalonia.Markup.UnitTests\Avalonia.Markup.UnitTests.csproj", "{8EF392D5-1416-45AA-9956-7CBBC3229E8A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Markup.UnitTests", "tests\Avalonia.Markup.UnitTests\Avalonia.Markup.UnitTests.csproj", "{8EF392D5-1416-45AA-9956-7CBBC3229E8A}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "BindingTest", "samples\BindingTest\BindingTest.csproj", "{08B3E6B9-1CD5-443C-9F61-6D49D1C5F162}"
 EndProject
@@ -87,14 +87,6 @@ Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "RenderHelpers", "src\Shared
 EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Skia", "Skia", "{3743B0F2-CC41-4F14-A8C8-267F579BF91E}"
 EndProject
-Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Avalonia.Skia", "src\Skia\Avalonia.Skia\Avalonia.Skia.shproj", "{2F59F3D0-748D-4652-B01E-E0D954756308}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.Desktop", "src\Skia\Avalonia.Skia.Desktop\Avalonia.Skia.Desktop.csproj", "{925DD807-B651-475F-9F7C-CBEB974CE43D}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.Android", "src\Skia\Avalonia.Skia.Android\Avalonia.Skia.Android.csproj", "{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}"
-EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.iOS", "src\Skia\Avalonia.Skia.iOS\Avalonia.Skia.iOS.csproj", "{47BE08A7-5985-410B-9FFC-2264B8EA595F}"
-EndProject
 Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Android", "Android", "{7CF9789C-F1D3-4D0E-90E5-F1DF67A2753F}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Android", "src\Android\Avalonia.Android\Avalonia.Android.csproj", "{7B92AF71-6287-4693-9DCB-BD5B6E927E23}"
@@ -109,22 +101,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.iOSTestApplication
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.LeakTests", "tests\Avalonia.LeakTests\Avalonia.LeakTests.csproj", "{E1AA3DBF-9056-4530-9376-18119A7A3FFE}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.UnitTests", "tests\Avalonia.UnitTests\Avalonia.UnitTests.csproj", "{88060192-33D5-4932-B0F9-8BD2763E857D}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.UnitTests", "tests\Avalonia.UnitTests\Avalonia.UnitTests.csproj", "{88060192-33D5-4932-B0F9-8BD2763E857D}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Benchmarks", "tests\Avalonia.Benchmarks\Avalonia.Benchmarks.csproj", "{410AC439-81A1-4EB5-B5E9-6A7FC6B77F4B}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Logging.Serilog", "src\Avalonia.Logging.Serilog\Avalonia.Logging.Serilog.csproj", "{B61B66A3-B82D-4875-8001-89D3394FE0C9}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Logging.Serilog", "src\Avalonia.Logging.Serilog\Avalonia.Logging.Serilog.csproj", "{B61B66A3-B82D-4875-8001-89D3394FE0C9}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DesignerSupport", "src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj", "{799A7BB5-3C2C-48B6-85A7-406A12C420DA}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DesignerSupport", "src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj", "{799A7BB5-3C2C-48B6-85A7-406A12C420DA}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog", "samples\ControlCatalog\ControlCatalog.csproj", "{D0A739B9-3C68-4BA6-A328-41606954B6BD}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.iOS", "samples\ControlCatalog.iOS\ControlCatalog.iOS.csproj", "{57E0455D-D565-44BB-B069-EE1AA20F8337}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}"
-EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DesignerSupport.Tests", "tests\Avalonia.DesignerSupport.Tests\Avalonia.DesignerSupport.Tests.csproj", "{52F55355-D120-42AC-8116-8410A7D602FA}"
 EndProject
 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DesignerSupport.TestApp", "tests\Avalonia.DesignerSupport.TestApp\Avalonia.DesignerSupport.TestApp.csproj", "{F1381F98-4D24-409A-A6C5-1C5B1E08BB08}"
@@ -147,15 +137,15 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.Android", "s
 EndProject
 Project("{D954291E-2A0B-460D-934E-DC6B0785DB48}") = "Avalonia.Win32.Shared", "src\Windows\Avalonia.Win32\Avalonia.Win32.Shared.shproj", "{9DEFC6B7-845B-4D8F-AFC0-D32BF0032B8C}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Win32.NetStandard", "src\Windows\Avalonia.Win32.NetStandard\Avalonia.Win32.NetStandard.csproj", "{40759A76-D0F2-464E-8000-6FF0F5C4BD7C}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Win32.NetStandard", "src\Windows\Avalonia.Win32.NetStandard\Avalonia.Win32.NetStandard.csproj", "{40759A76-D0F2-464E-8000-6FF0F5C4BD7C}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.DotNetCoreRuntime", "src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj", "{7863EA94-F0FB-4386-BF8C-E5BFA761560A}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.DotNetCoreRuntime", "src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj", "{7863EA94-F0FB-4386-BF8C-E5BFA761560A}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Skia.Desktop.NetStandard", "src\Skia\Avalonia.Skia.Desktop.NetStandard\Avalonia.Skia.Desktop.NetStandard.csproj", "{7D2D3083-71DD-4CC9-8907-39A0D86FB322}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia", "src\Skia\Avalonia.Skia\Avalonia.Skia.csproj", "{7D2D3083-71DD-4CC9-8907-39A0D86FB322}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Gtk3", "src\Gtk\Avalonia.Gtk3\Avalonia.Gtk3.csproj", "{BB1F7BB5-6AD4-4776-94D9-C09D0A972658}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Gtk3", "src\Gtk\Avalonia.Gtk3\Avalonia.Gtk3.csproj", "{BB1F7BB5-6AD4-4776-94D9-C09D0A972658}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ControlCatalog.NetCore", "samples\ControlCatalog.NetCore\ControlCatalog.NetCore.csproj", "{39D7B147-1A5B-47C2-9D01-21FB7C47C4B3}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "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
@@ -187,32 +177,27 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Targets", "Targets", "{4D6F
 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}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.LinuxFramebuffer", "src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj", "{854568D5-13D1-4B4F-B50D-534DC7EFD3C9}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Direct3DInteropSample", "samples\interop\Direct3DInteropSample\Direct3DInteropSample.csproj", "{638580B0-7910-40EF-B674-DCB34DA308CD}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Avalonia.Win32.Interop", "src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj", "{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}"
 EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Direct3DInteropSample", "samples\interop\Direct3DInteropSample\Direct3DInteropSample.csproj", "{638580B0-7910-40EF-B674-DCB34DA308CD}"
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Avalonia.Skia.RenderTests", "tests\Avalonia.RenderTests\Avalonia.Skia.RenderTests.csproj", "{E1582370-37B3-403C-917F-8209551B1634}"
 EndProject
 Global
 	GlobalSection(SharedMSBuildProjectFiles) = preSolution
-		src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{2f59f3d0-748d-4652-b01e-e0d954756308}*SharedItemsImports = 13
 		src\Shared\RenderHelpers\RenderHelpers.projitems*{3c4c0cb4-0c0f-4450-a37b-148c84ff905f}*SharedItemsImports = 13
 		src\Shared\RenderHelpers\RenderHelpers.projitems*{3e908f67-5543-4879-a1dc-08eace79b3cd}*SharedItemsImports = 4
 		src\Windows\Avalonia.Win32\Avalonia.Win32.Shared.projitems*{40759a76-d0f2-464e-8000-6ff0f5c4bd7c}*SharedItemsImports = 4
 		src\Shared\PlatformSupport\PlatformSupport.projitems*{4488ad85-1495-4809-9aa4-ddfe0a48527e}*SharedItemsImports = 4
-		src\Shared\RenderHelpers\RenderHelpers.projitems*{47be08a7-5985-410b-9ffc-2264b8ea595f}*SharedItemsImports = 4
-		src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{47be08a7-5985-410b-9ffc-2264b8ea595f}*SharedItemsImports = 4
 		tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{48840edd-24bf-495d-911e-2eb12ae75d3b}*SharedItemsImports = 13
 		src\Shared\PlatformSupport\PlatformSupport.projitems*{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}*SharedItemsImports = 4
 		src\Shared\PlatformSupport\PlatformSupport.projitems*{7863ea94-f0fb-4386-bf8c-e5bfa761560a}*SharedItemsImports = 4
 		src\Shared\PlatformSupport\PlatformSupport.projitems*{7b92af71-6287-4693-9dcb-bd5b6e927e23}*SharedItemsImports = 4
 		src\Shared\RenderHelpers\RenderHelpers.projitems*{7d2d3083-71dd-4cc9-8907-39a0d86fb322}*SharedItemsImports = 4
-		src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{7d2d3083-71dd-4cc9-8907-39a0d86fb322}*SharedItemsImports = 4
 		src\Windows\Avalonia.Win32\Avalonia.Win32.Shared.projitems*{811a76cf-1cf6-440f-963b-bbe31bd72a82}*SharedItemsImports = 4
-		src\Shared\RenderHelpers\RenderHelpers.projitems*{925dd807-b651-475f-9f7c-cbeb974ce43d}*SharedItemsImports = 4
-		src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{925dd807-b651-475f-9f7c-cbeb974ce43d}*SharedItemsImports = 4
 		src\Windows\Avalonia.Win32\Avalonia.Win32.Shared.projitems*{9defc6b7-845b-4d8f-afc0-d32bf0032b8c}*SharedItemsImports = 13
-		src\Shared\RenderHelpers\RenderHelpers.projitems*{bd43f7c0-396b-4aa1-bad9-dfde54d51298}*SharedItemsImports = 4
-		src\Skia\Avalonia.Skia\Avalonia.Skia.projitems*{bd43f7c0-396b-4aa1-bad9-dfde54d51298}*SharedItemsImports = 4
-		tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{d35a9f3d-8bb0-496e-bf72-444038a7debb}*SharedItemsImports = 4
 		tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{dabfd304-d6a4-4752-8123-c2ccf7ac7831}*SharedItemsImports = 4
 		tests\Avalonia.RenderTests\Avalonia.RenderTests.projitems*{e106cf37-4066-4615-b684-172a6d30b058}*SharedItemsImports = 4
 		src\Shared\PlatformSupport\PlatformSupport.projitems*{e4d9629c-f168-4224-3f51-a5e482ffbc42}*SharedItemsImports = 13
@@ -1443,110 +1428,6 @@ Global
 		{08B3E6B9-1CD5-443C-9F61-6D49D1C5F162}.Release|Mono.Build.0 = Release|Any CPU
 		{08B3E6B9-1CD5-443C-9F61-6D49D1C5F162}.Release|x86.ActiveCfg = Release|Any CPU
 		{08B3E6B9-1CD5-443C-9F61-6D49D1C5F162}.Release|x86.Build.0 = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Ad-Hoc|Mono.ActiveCfg = Debug|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Ad-Hoc|x86.ActiveCfg = Release|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Ad-Hoc|x86.Build.0 = Release|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.AppStore|Mono.ActiveCfg = Debug|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.AppStore|x86.ActiveCfg = Release|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.AppStore|x86.Build.0 = Release|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Debug|Any CPU.ActiveCfg = Debug|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Debug|Any CPU.Build.0 = Debug|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Debug|iPhone.ActiveCfg = Debug|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Debug|iPhone.Build.0 = Debug|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Debug|Mono.ActiveCfg = Debug|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Debug|x86.ActiveCfg = Debug|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Debug|x86.Build.0 = Debug|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Release|Any CPU.ActiveCfg = Release|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Release|Any CPU.Build.0 = Release|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Release|iPhone.Build.0 = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Release|Mono.ActiveCfg = Release|Any CPU
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Release|x86.ActiveCfg = Release|x86
-		{925DD807-B651-475F-9F7C-CBEB974CE43D}.Release|x86.Build.0 = Release|x86
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Ad-Hoc|Mono.ActiveCfg = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.AppStore|Mono.ActiveCfg = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.AppStore|x86.ActiveCfg = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.AppStore|x86.Build.0 = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Debug|Mono.ActiveCfg = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Debug|x86.Build.0 = Debug|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|Any CPU.Build.0 = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|Mono.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|x86.ActiveCfg = Release|Any CPU
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298}.Release|x86.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Ad-Hoc|Mono.ActiveCfg = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.AppStore|Mono.ActiveCfg = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.AppStore|x86.ActiveCfg = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.AppStore|x86.Build.0 = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Debug|Any CPU.Build.0 = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Debug|iPhone.ActiveCfg = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Debug|iPhone.Build.0 = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Debug|Mono.ActiveCfg = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Debug|x86.ActiveCfg = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Debug|x86.Build.0 = Debug|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Release|Any CPU.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Release|Any CPU.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Release|iPhone.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Release|Mono.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Release|x86.ActiveCfg = Release|Any CPU
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F}.Release|x86.Build.0 = Release|Any CPU
 		{7B92AF71-6287-4693-9DCB-BD5B6E927E23}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{7B92AF71-6287-4693-9DCB-BD5B6E927E23}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
 		{7B92AF71-6287-4693-9DCB-BD5B6E927E23}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
@@ -1953,42 +1834,6 @@ Global
 		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|iPhoneSimulator.Build.0 = Release|iPhoneSimulator
 		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|Mono.ActiveCfg = Release|iPhoneSimulator
 		{57E0455D-D565-44BB-B069-EE1AA20F8337}.Release|x86.ActiveCfg = Release|iPhone
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Ad-Hoc|Mono.ActiveCfg = Debug|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Ad-Hoc|x86.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.AppStore|Any CPU.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.AppStore|iPhone.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.AppStore|iPhone.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.AppStore|Mono.ActiveCfg = Debug|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.AppStore|x86.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.AppStore|x86.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Debug|Any CPU.ActiveCfg = Debug|x86
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Debug|Any CPU.Build.0 = Debug|x86
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Debug|iPhone.ActiveCfg = Debug|x86
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Debug|iPhone.Build.0 = Debug|x86
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Debug|Mono.ActiveCfg = Debug|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Debug|x86.ActiveCfg = Debug|x86
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Debug|x86.Build.0 = Debug|x86
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Release|Any CPU.ActiveCfg = Release|x86
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Release|Any CPU.Build.0 = Release|x86
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Release|iPhone.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Release|iPhone.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Release|Mono.ActiveCfg = Release|Any CPU
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Release|x86.ActiveCfg = Release|x86
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB}.Release|x86.Build.0 = Release|x86
 		{52F55355-D120-42AC-8116-8410A7D602FA}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
 		{52F55355-D120-42AC-8116-8410A7D602FA}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
 		{52F55355-D120-42AC-8116-8410A7D602FA}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
@@ -2589,6 +2434,86 @@ Global
 		{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
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|Any CPU.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|Any CPU.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|iPhone.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|iPhone.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|iPhoneSimulator.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|Mono.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|Mono.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|x86.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Ad-Hoc|x86.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|Any CPU.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|Any CPU.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|iPhone.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|iPhone.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|iPhoneSimulator.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|Mono.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|Mono.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|x86.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.AppStore|x86.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Mono.ActiveCfg = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|Mono.Build.0 = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Debug|x86.Build.0 = Debug|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|Any CPU.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|iPhone.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|Mono.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|Mono.Build.0 = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|x86.ActiveCfg = Release|Any CPU
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E}.Release|x86.Build.0 = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|Any CPU.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|Any CPU.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|iPhone.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|iPhone.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|Mono.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|Mono.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|x86.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Ad-Hoc|x86.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|Any CPU.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|Any CPU.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|iPhone.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|iPhone.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|Mono.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|Mono.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|x86.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.AppStore|x86.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|Any CPU.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|iPhone.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|iPhone.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|Mono.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|Mono.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|x86.ActiveCfg = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Debug|x86.Build.0 = Debug|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|Any CPU.ActiveCfg = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|Any CPU.Build.0 = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|iPhone.ActiveCfg = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|iPhone.Build.0 = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|Mono.ActiveCfg = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|Mono.Build.0 = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|x86.ActiveCfg = Release|Any CPU
+		{E1582370-37B3-403C-917F-8209551B1634}.Release|x86.Build.0 = Release|Any CPU
 	EndGlobalSection
 	GlobalSection(SolutionProperties) = preSolution
 		HideSolutionNode = FALSE
@@ -2616,10 +2541,6 @@ Global
 		{8EF392D5-1416-45AA-9956-7CBBC3229E8A} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{08B3E6B9-1CD5-443C-9F61-6D49D1C5F162} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{3C4C0CB4-0C0F-4450-A37B-148C84FF905F} = {A689DEF5-D50F-4975-8B72-124C9EB54066}
-		{2F59F3D0-748D-4652-B01E-E0D954756308} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
-		{925DD807-B651-475F-9F7C-CBEB974CE43D} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
-		{BD43F7C0-396B-4AA1-BAD9-DFDE54D51298} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
-		{47BE08A7-5985-410B-9FFC-2264B8EA595F} = {3743B0F2-CC41-4F14-A8C8-267F579BF91E}
 		{7B92AF71-6287-4693-9DCB-BD5B6E927E23} = {7CF9789C-F1D3-4D0E-90E5-F1DF67A2753F}
 		{FF69B927-C545-49AE-8E16-3D14D621AA12} = {7CF9789C-F1D3-4D0E-90E5-F1DF67A2753F}
 		{4488AD85-1495-4809-9AA4-DDFE0A48527E} = {0CB0B92E-6CFF-4240-80A5-CCAFE75D91E1}
@@ -2630,7 +2551,6 @@ Global
 		{D0A739B9-3C68-4BA6-A328-41606954B6BD} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{2B888490-D14A-4BCA-AB4B-48676FA93C9B} = {9B9E3891-2366-4253-A952-D08BCEB71098}
 		{57E0455D-D565-44BB-B069-EE1AA20F8337} = {9B9E3891-2366-4253-A952-D08BCEB71098}
-		{D35A9F3D-8BB0-496E-BF72-444038A7DEBB} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{52F55355-D120-42AC-8116-8410A7D602FA} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{F1381F98-4D24-409A-A6C5-1C5B1E08BB08} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 		{48840EDD-24BF-495D-911E-2EB12AE75D3B} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
@@ -2649,5 +2569,7 @@ Global
 		{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}
+		{CBC4FF2F-92D4-420B-BE21-9FE0B930B04E} = {B39A8919-9F95-48FE-AD7B-76E08B509888}
+		{E1582370-37B3-403C-917F-8209551B1634} = {C5A00AC3-B34C-4564-9BDD-2DA473EF4D8B}
 	EndGlobalSection
 EndGlobal

+ 3 - 4
appveyor.yml

@@ -14,19 +14,18 @@ environment:
     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")
+- ps: if (Test-Path env:nuget_address) {[System.IO.File]::AppendAllText("C:\Windows\System32\drivers\etc\hosts", "`n$($env:nuget_address)`tapi.nuget.org")}
 install:
   - if not exist gtk-sharp-2.12.26.msi appveyor DownloadFile http://download.xamarin.com/GTKforWindows/Windows/gtk-sharp-2.12.26.msi
-  - if not exist dotnet-1.0.1.exe appveyor DownloadFile https://go.microsoft.com/fwlink/?linkid=843448 -FileName "dotnet-1.0.1.exe"
+  - if not exist dotnet-2.0.0.exe appveyor DownloadFile https://download.microsoft.com/download/0/F/D/0FD852A4-7EA1-4E2A-983A-0484AC19B92C/dotnet-sdk-2.0.0-win-x64.exe -FileName "dotnet-2.0.0.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
+  - ps: Start-Process -FilePath "dotnet-2.0.0.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:
-- 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"

+ 72 - 54
build.cake

@@ -4,15 +4,14 @@
 
 #addin "nuget:?package=Polly&version=4.2.0"
 #addin "nuget:?package=NuGet.Core&version=2.12.0"
+#tool "nuget:?package=xunit.runner.console&version=2.2.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.3.20160517.113140"
-#tool "JetBrains.ReSharper.CommandLineTools"
+#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2017.1.20170613.162720"
 ///////////////////////////////////////////////////////////////////////////////
 // TOOLS
 ///////////////////////////////////////////////////////////////////////////////
 
-#tool "nuget:?package=xunit.runner.console&version=2.1.0"
-#tool "nuget:?package=OpenCover"
+#tool "nuget:?package=xunit.runner.console&version=2.2.0"
 
 ///////////////////////////////////////////////////////////////////////////////
 // USINGS
@@ -98,7 +97,6 @@ Task("Clean")
     CleanDirectory(parameters.TestsRoot);
 });
 
-
 Task("Restore-NuGet-Packages")
     .IsDependentOn("Clean")
     .WithCriteria(parameters.IsRunningOnWindows)
@@ -120,7 +118,6 @@ Task("Restore-NuGet-Packages")
             }})
         .Execute(()=> {
                 NuGetRestore(parameters.MSBuildSolution, new NuGetRestoreSettings {
-                    ToolPath = "./tools/NuGet.CommandLine/tools/NuGet.exe",
                     ToolTimeout = TimeSpan.FromMinutes(toolTimeout)
                 });
         });
@@ -158,41 +155,50 @@ Task("Build")
     }
 });
 
-void RunCoreTest(string dir, Parameters parameters, bool net461Only)
+
+void RunCoreTest(string project, Parameters parameters, bool coreOnly = false)
 {
-    Information("Running tests from " + dir);
-    DotNetCoreRestore(dir);
-    var frameworks = new List<string>(){"netcoreapp1.1"};
+    if(!project.EndsWith(".csproj"))
+        project = System.IO.Path.Combine(project, System.IO.Path.GetFileName(project)+".csproj");
+    Information("Running tests from " + project);
+    DotNetCoreRestore(project);
+    var frameworks = new List<string>(){"netcoreapp2.0"};
     if(parameters.IsRunningOnWindows)
         frameworks.Add("net461");
     foreach(var fw in frameworks)
     {
-        if(fw != "net461" && net461Only)
+        if(!fw.StartsWith("netcoreapp") && coreOnly)
             continue;
         Information("Running for " + fw);
-        DotNetCoreTest(System.IO.Path.Combine(dir, System.IO.Path.GetFileName(dir)+".csproj"),
-            new DotNetCoreTestSettings{Framework = fw});
+        
+        DotNetCoreTest(project,
+            new DotNetCoreTestSettings {
+                Configuration = parameters.Configuration,
+                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);
+        RunCoreTest("./tests/Avalonia.Controls.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Input.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Layout.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Markup.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Styling.UnitTests", parameters, false);
+        RunCoreTest("./tests/Avalonia.Visuals.UnitTests", parameters, false);
+        if(parameters.IsRunningOnWindows)
+            RunCoreTest("./tests/Avalonia.RenderTests/Avalonia.Skia.RenderTests.csproj", parameters, true);
     });
 
 Task("Run-Unit-Tests")
     .IsDependentOn("Run-Net-Core-Unit-Tests")
     .IsDependentOn("Build")
+    //.IsDependentOn("Run-Leak-Tests")
     .WithCriteria(() => !parameters.SkipTests)
     .Does(() =>
 {
@@ -201,17 +207,11 @@ Task("Run-Unit-Tests")
 
     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))
+        .Where( name => !name.Contains("Skia")) // Run in the Run-Net-Core-Unit-Tests target
+        .Where(name => parameters.IsRunningOnWindows ? true : !name.Contains("Direct2D"))
         .Select(name => MakeAbsolute(File("./tests/" + name + "/bin/" + parameters.DirSuffix + "/" + name + ".dll")))
         .ToList();
 
-    if (parameters.IsRunningOnWindows)
-    {
-        var leakTests = GetFiles("./tests/Avalonia.LeakTests/bin/" + parameters.DirSuffix + "/*.LeakTests.dll");
-
-        unitTests.AddRange(leakTests);
-    }
-
     var toolPath = (parameters.IsPlatformAnyCPU || parameters.IsPlatformX86) ? 
         "./tools/xunit.runner.console/tools/xunit.console.x86.exe" :
         "./tools/xunit.runner.console/tools/xunit.console.exe";
@@ -225,23 +225,11 @@ Task("Run-Unit-Tests")
 
     xUnitSettings.NoAppDomain = !parameters.IsRunningOnWindows;
 
-    var openCoverOutput = parameters.ArtifactsDir.GetFilePath(new FilePath("./coverage.xml"));
-    var openCoverSettings = new OpenCoverSettings()
-        .WithFilter("+[Avalonia.*]* -[*Test*]* -[ControlCatalog*]*")
-        .WithFilter("-[Avalonia.*]OmniXaml.* -[Avalonia.*]Glass.*")
-        .WithFilter("-[Avalonia.HtmlRenderer]TheArtOfDev.HtmlRenderer.* +[Avalonia.HtmlRenderer]TheArtOfDev.HtmlRenderer.Avalonia.* -[Avalonia.ReactiveUI]*");
-    
-    openCoverSettings.ReturnTargetCodeOffset = 0;
-
     foreach(var test in unitTests.Where(testFile => FileExists(testFile)))
     {
         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)
     {
@@ -252,16 +240,7 @@ Task("Run-Unit-Tests")
         testsInDirectoryToRun.AddRange(GetFiles("./artifacts/tests/*.UnitTests.dll"));
     }
 
-    if(parameters.IsRunningOnWindows)
-    {
-        OpenCover(context => {
-            context.XUnit2(testsInDirectoryToRun, xUnitSettings);
-        }, openCoverOutput, openCoverSettings);
-    }
-    else
-    {
-        XUnit2(testsInDirectoryToRun, xUnitSettings);
-    }
+    XUnit2(testsInDirectoryToRun, xUnitSettings);
 });
 
 Task("Copy-Files")
@@ -364,6 +343,44 @@ Task("Publish-NuGet")
     Information("Publish-NuGet Task failed, but continuing with next Task...");
 });
 
+Task("Run-Leak-Tests")
+    .WithCriteria(parameters.IsRunningOnWindows)
+    .IsDependentOn("Build")
+    .Does(() =>
+    {
+        DotNetCoreRestore("tests\\Avalonia.LeakTests\\toolproject\\tool.csproj");
+        DotNetBuild("tests\\Avalonia.LeakTests\\toolproject\\tool.csproj", settings => settings.SetConfiguration("Release"));
+        var report = "tests\\Avalonia.LeakTests\\bin\\Release\\report.xml";
+        if(System.IO.File.Exists(report))
+            System.IO.File.Delete(report);
+        var proc = System.Diagnostics.Process.Start(new System.Diagnostics.ProcessStartInfo
+        {
+            FileName="tests\\Avalonia.LeakTests\\toolproject\\bin\\dotMemoryUnit.exe",
+            Arguments="-targetExecutable=\"tools\\xunit.runner.console\\tools\\xunit.console.x86.exe\" -returnTargetExitCode  -- tests\\Avalonia.LeakTests\\bin\\Release\\Avalonia.LeakTests.dll -xml tests\\Avalonia.LeakTests\\bin\\Release\\report.xml ",
+            UseShellExecute = false,
+        });
+        var st = System.Diagnostics.Stopwatch.StartNew();
+        while(!proc.HasExited && !System.IO.File.Exists(report))
+        {
+            if(st.Elapsed.TotalSeconds>60)
+            {
+                Error("Timed out, probably a bug in dotMemoryUnit");
+                proc.Kill();
+                throw new Exception("dotMemory issue");
+            }
+            proc.WaitForExit(100);
+        }
+        try{
+            proc.Kill();
+        }catch{}
+        var doc =  System.Xml.Linq.XDocument.Load(report);
+        if(doc.Root.Descendants("assembly").Any(x=>x.Attribute("failed").Value.ToString() != "0"))
+        {
+            throw new Exception("Tests failed");
+        }
+
+    });
+
 Task("Inspect")
     .WithCriteria(parameters.IsRunningOnWindows)
     .IsDependentOn("Restore-NuGet-Packages")
@@ -371,7 +388,8 @@ Task("Inspect")
     {
         var badIssues = new []{"PossibleNullReferenceException"};
         var whitelist = new []{"tests", "src\\android", "src\\ios",
-            "src\\windows\\avalonia.designer", "src\\avalonia.htmlrenderer\\external"};
+            "src\\windows\\avalonia.designer", "src\\avalonia.htmlrenderer\\external",
+            "src\\markup\\avalonia.markup.xaml\\portablexaml\\portable.xaml.github"};
         Information("Running code inspections");
         
         

+ 5 - 0
build/Base.props

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

+ 1 - 1
build/Magick.NET-Q16-AnyCPU.props

@@ -1,5 +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" />
+    <PackageReference Include="Magick.NET-Q16-AnyCPU" Version="7.0.6.102" />
   </ItemGroup>
 </Project>

+ 5 - 0
build/Markup.props

@@ -5,5 +5,10 @@
     <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" />
+    <PackageReference Include="System.ComponentModel.TypeConverter" Version="4.3.0" />
+    <PackageReference Include="System.ComponentModel.Primitives" Version="4.3.0" />
+    <PackageReference Include="System.Runtime.Serialization.Primitives" Version="4.3.0" />
+    <PackageReference Include="System.Xml.XmlDocument" Version="4.3.0" />
+    <PackageReference Include="System.Xml.ReaderWriter" Version="4.3.0" />
   </ItemGroup>
 </Project>

+ 1 - 1
build/Moq.props

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

+ 5 - 4
build/SharpDX.props

@@ -1,8 +1,9 @@
 <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" />
+    <PackageReference Include="SharpDX" Version="4.0.1" />
+    <PackageReference Include="SharpDX.Direct2D1" Version="4.0.1" />
+    <PackageReference Include="SharpDX.Direct3D11" Version="4.0.1" />
+    <PackageReference Include="SharpDX.DXGI" Version="4.0.1" />
+    <PackageReference Include="SharpDX.Direct3D9" Version="4.0.1" Condition="'$(UseDirect3D9)' == 'true'" />
   </ItemGroup>
 </Project>

+ 1 - 1
build/SkiaSharp.props

@@ -1,6 +1,6 @@
 <Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
   <ItemGroup>
     <PackageReference Include="SkiaSharp" Version="1.57.1" />
-    <PackageReference Condition="$(TargetFramework.Trim('.').ToLower().StartsWith('netframework'))" Include="Avalonia.Skia.Linux.Natives" Version="1.57.1.3" />
+    <PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="Avalonia.Skia.Linux.Natives" Version="1.57.1.3" />
   </ItemGroup>
 </Project>

+ 0 - 20
build/UnitTests.NetCore.targets

@@ -3,27 +3,7 @@
     <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>

+ 16 - 2
build/XUnit.props

@@ -7,7 +7,21 @@
     <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" />
+    <PackageReference Include="xunit.runner.visualstudio" Version="2.2.0" />
   </ItemGroup>
+  <ItemGroup Condition="'$(TargetFramework)' == 'netcoreapp2.0'">
+    <PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.0.0" />
+  </ItemGroup>
+  <PropertyGroup>
+    <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
+  </PropertyGroup>
+  <Target Name="ForceGenerationOfBindingRedirects"
+          AfterTargets="ResolveAssemblyReferences"
+          BeforeTargets="GenerateBindingRedirects"
+          Condition="'$(AutoGenerateBindingRedirects)' == 'true'">
+    <PropertyGroup>
+      <!-- Needs to be set in a target because it has to be set after the initial evaluation in the common targets -->
+      <GenerateBindingRedirectsOutputType>true</GenerateBindingRedirectsOutputType>
+    </PropertyGroup>
+  </Target>
 </Project>

+ 7 - 6
docs/guidelines/build.md

@@ -80,10 +80,11 @@ mono ./samples/ControlCatalog.Desktop/bin/Debug/ControlCatalog.Desktop.exe
 
 ### Building Avalonia in MonoDevelop
 
-Unless you have a very current version of monodevelop (6.1.x or newer), it is necessary to manually
-restore the Nuget depdendencies as [mentioned above](#restore-nuget-packages). You must then
-disable MonoDevelop's inbuilt NuGet package manager add-in by going to `Tools -> Add-in Manager` or
-it will complain that a newer version of NuGet is needed.
+Flatpak version will *NOT* work. Version from https://github.com/cra0zy/monodevelop-run-installer/ might work if you are very lucky. Make sure that you have the latest version of Mono (from alpha update channel) and .NET Core SDK. Make sure to follow `FrameworkPathOverride` workaround from https://github.com/dotnet/sdk/issues/335
+
+### Building and running Avalonia in Rider
+
+For Linux/OSX you'll probably need to apply workaround from https://github.com/dotnet/sdk/issues/335
+
+Just add `export FrameworkPathOverride=/usr/lib/mono/4.6.1-api` (or `export FrameworkPathOverride=/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.6.1-api` for OSX)
 
-Finally, select the `Debug | Mono` or `Release | Mono` build configuration and you should be good to
-go!

+ 2 - 2
docs/tutorial/from-wpf.md

@@ -33,7 +33,7 @@ placed in a `DataTemplates` collection on each control (and on `Application`):
                     <TextBox Text="{Binding Name}"/>
                 </Border>
             </DataTemplate>
-        </UserControl.Styles>
+        </UserControl.DataTemplates>
         <!-- Assuming that DataContext.Foo is an object of type
              MyApp.ViewModels.FooViewModel then a red border with a corner
              radius of 8 containing a TextBox will be displayed here -->
@@ -161,7 +161,7 @@ the same way that event class listeners are added](../spec/working-with-properti
 
 ## RenderTransforms and RenderTransformOrigin
 
-RenderTransformOrigins are different in WPF and Avalonia: If you apply a `RenderTransform`, keep in mind that our default value for the RenderTransformOrigin is `RelativePoint.Middle`. In WPF the default value is `RelativePoint.TopLeft` (0, 0). In controls like Viewbox (currently being developed) the same code will lead to a different rendering behavior:
+RenderTransformOrigins are different in WPF and Avalonia: If you apply a `RenderTransform`, keep in mind that our default value for the RenderTransformOrigin is `RelativePoint.Center`. In WPF the default value is `RelativePoint.TopLeft` (0, 0). In controls like Viewbox (currently being developed) the same code will lead to a different rendering behavior:
 
 In WPF:
 ![WPF](https://files.gitter.im/AvaloniaUI/Avalonia/cDrM/image.png)

+ 100 - 91
packages.cake

@@ -8,6 +8,41 @@ public class Packages
     public string NugetPackagesDir {get; private set;}
     public string SkiaSharpVersion {get; private set; }
     public string SkiaSharpLinuxVersion {get; private set; }
+    public Dictionary<string, IList<Tuple<string,string>>> PackageVersions{get; private set;}
+    
+       
+    
+    class DependencyBuilder : List<NuSpecDependency>
+    {
+        Packages _parent;
+        public DependencyBuilder(Packages parent)
+        {
+            _parent = parent;
+        }
+        
+        string GetVersion(string name)
+        {
+            return _parent.PackageVersions[name].First().Item1;
+        }
+        
+        
+        public DependencyBuilder Dep(string name, params string[] fws)
+        {
+            if(fws.Length == 0)
+                Add(new NuSpecDependency() { Id = name, Version = GetVersion(name) });
+            foreach(var fw in fws)
+                Add(new NuSpecDependency() { Id = name, TargetFramework = fw, Version = GetVersion(name) });
+            return this;
+        }
+        public DependencyBuilder Deps(string[] fws, params string[] deps)
+        {
+            foreach(var fw in fws)
+                foreach(var name in deps)
+                    Add(new NuSpecDependency() { Id = name, TargetFramework = fw, Version = GetVersion(name) });
+            return this;
+        }
+    }
+        
     public Packages(ICakeContext context, Parameters parameters)
     {
         // NUGET NUSPECS
@@ -26,7 +61,7 @@ public class Packages
         // Key: Package Id
         // Value is Tuple where Item1: Package Version, Item2: The *.csproj/*.props file path.
         var packageVersions = new Dictionary<string, IList<Tuple<string,string>>>();
-
+        PackageVersions = packageVersions;
         System.IO.Directory.EnumerateFiles(((DirectoryPath)context.Directory("./build")).FullPath,
             "*.props", SearchOption.AllDirectories).ToList().ForEach(fileName =>
         {
@@ -75,22 +110,26 @@ public class Packages
         var SplatVersion = packageVersions["Splat"].FirstOrDefault().Item1;
         var SpracheVersion = packageVersions["Sprache"].FirstOrDefault().Item1;
         var SystemReactiveVersion = packageVersions["System.Reactive"].FirstOrDefault().Item1;
+        var SystemValueTupleVersion = packageVersions["System.ValueTuple"].FirstOrDefault().Item1;
         SkiaSharpVersion = packageVersions["SkiaSharp"].FirstOrDefault().Item1;
 		SkiaSharpLinuxVersion = packageVersions["Avalonia.Skia.Linux.Natives"].FirstOrDefault().Item1;
         var SharpDXVersion = packageVersions["SharpDX"].FirstOrDefault().Item1;
         var SharpDXDirect2D1Version = packageVersions["SharpDX.Direct2D1"].FirstOrDefault().Item1;
         var SharpDXDirect3D11Version = packageVersions["SharpDX.Direct3D11"].FirstOrDefault().Item1;
+        var SharpDXDirect3D9Version = packageVersions["SharpDX.Direct3D9"].FirstOrDefault().Item1;
         var SharpDXDXGIVersion = packageVersions["SharpDX.DXGI"].FirstOrDefault().Item1;
 
         context.Information("Package: Serilog, version: {0}", SerilogVersion);
         context.Information("Package: Splat, version: {0}", SplatVersion);
         context.Information("Package: Sprache, version: {0}", SpracheVersion);
         context.Information("Package: System.Reactive, version: {0}", SystemReactiveVersion);
+        context.Information("Package: System.ValueTuple, version: {0}", SystemValueTupleVersion);
         context.Information("Package: SkiaSharp, version: {0}", SkiaSharpVersion);
         context.Information("Package: Avalonia.Skia.Linux.Natives, version: {0}", SkiaSharpLinuxVersion);
         context.Information("Package: SharpDX, version: {0}", SharpDXVersion);
         context.Information("Package: SharpDX.Direct2D1, version: {0}", SharpDXDirect2D1Version);
         context.Information("Package: SharpDX.Direct3D11, version: {0}", SharpDXDirect3D11Version);
+        context.Information("Package: SharpDX.Direct3D9, version: {0}", SharpDXDirect3D9Version);
         context.Information("Package: SharpDX.DXGI, version: {0}", SharpDXDXGIVersion);
 
         var nugetPackagesDir = System.Environment.GetEnvironmentVariable("NUGET_HOME")
@@ -146,12 +185,12 @@ public class Packages
         };
 
         var coreLibrariesFiles = coreLibraries.Select((lib) => {
-            return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard1.1/" + lib[1] + lib[2]);
+            return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard2.0/" + lib[1] + lib[2]);
         }).ToList();
 
         var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
             return new NuSpecContent { 
-                Source = file.FullPath, Target = "lib/netstandard1.1" 
+                Source = file.FullPath, Target = "lib/netstandard2.0" 
             };
         });
 
@@ -163,14 +202,14 @@ public class Packages
 
         var netcoreappCoreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
             return new NuSpecContent { 
-                Source = file.FullPath, Target = "lib/netcoreapp1.0" 
+                Source = file.FullPath, Target = "lib/netcoreapp2.0" 
             };
         });
 
         var net45RuntimePlatformExtensions = new [] {".xml", ".dll"};
         var net45RuntimePlatform = net45RuntimePlatformExtensions.Select(libSuffix => {
             return new NuSpecContent {
-                Source = ((FilePath)context.File("./src/Avalonia.DotNetFrameworkRuntime/bin/" + parameters.DirSuffix + "/Avalonia.DotNetFrameworkRuntime" + libSuffix)).FullPath, 
+                Source = ((FilePath)context.File("./src/Avalonia.DotNetFrameworkRuntime/bin/" + parameters.DirSuffix + "/net461/Avalonia.DotNetFrameworkRuntime" + libSuffix)).FullPath, 
                 Target = "lib/net45" 
             };
         });
@@ -178,8 +217,8 @@ 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 + "/netcoreapp1.0/Avalonia.DotNetCoreRuntime" + libSuffix)).FullPath, 
-                Target = "lib/netcoreapp1.0" 
+                Source = ((FilePath)context.File("./src/Avalonia.DotNetCoreRuntime/bin/" + parameters.DirSuffix + "/netcoreapp2.0/Avalonia.DotNetCoreRuntime" + libSuffix)).FullPath, 
+                Target = "lib/netcoreapp2.0" 
             };
         });
 
@@ -191,21 +230,25 @@ public class Packages
             new NuGetPackSettings()
             {
                 Id = "Avalonia",
-                Dependencies = new []
+                Dependencies = new DependencyBuilder(this)
                 {
                     new NuSpecDependency() { Id = "Serilog", Version = SerilogVersion },
                     new NuSpecDependency() { Id = "Splat", Version = SplatVersion },
                     new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion },
                     new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion },
                     //.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 = "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 }
-                },
+                    new NuSpecDependency() { Id = "System.Threading.ThreadPool", TargetFramework = "netcoreapp2.0", Version = "4.3.0" },
+                    new NuSpecDependency() { Id = "Microsoft.Extensions.DependencyModel", TargetFramework = "netcoreapp2.0", Version = "1.1.0" },
+                    new NuSpecDependency() { Id = "NETStandard.Library", TargetFramework = "netcoreapp2.0", Version = "1.6.0" },
+                    new NuSpecDependency() { Id = "Splat", TargetFramework = "netcoreapp2.0", Version = SplatVersion },
+                    new NuSpecDependency() { Id = "Serilog", TargetFramework = "netcoreapp2.0", Version = SerilogVersion },
+                    new NuSpecDependency() { Id = "Sprache", TargetFramework = "netcoreapp2.0", Version = SpracheVersion },
+                    new NuSpecDependency() { Id = "System.Reactive", TargetFramework = "netcoreapp2.0", Version = SystemReactiveVersion },
+                }
+                .Deps(new string[]{null, "netcoreapp2.0"},
+                    "System.ValueTuple", "System.ComponentModel.TypeConverter", "System.ComponentModel.Primitives",
+                    "System.Runtime.Serialization.Primitives", "System.Xml.XmlDocument", "System.Xml.ReaderWriter")
+                .ToArray(),
                 Files = coreLibrariesNuSpecContent
                     .Concat(win32CoreLibrariesNuSpecContent).Concat(net45RuntimePlatform)
                     .Concat(netcoreappCoreLibrariesNuSpecContent).Concat(netCoreRuntimePlatform)
@@ -225,9 +268,9 @@ public class Packages
                 },
                 Files = new []
                 {
-                    new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/netstandard1.1" }
+                    new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/netstandard2.0" }
                 },
-                BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix + "/netstandard1.1"),
+                BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix + "/netstandard2.0"),
                 OutputDirectory = parameters.NugetRoot
             }
         };
@@ -243,7 +286,7 @@ public class Packages
                 Dependencies = new []
                 {
                     new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "Avalonia.Skia.Android", Version = parameters.Version }
+                    new NuSpecDependency() { Id = "Avalonia.Skia", Version = parameters.Version }
                 },
                 Files = new []
                 {
@@ -253,24 +296,6 @@ public class Packages
                 OutputDirectory = parameters.NugetRoot
             },
             ///////////////////////////////////////////////////////////////////////////////
-            // Avalonia.Skia.Android
-            ///////////////////////////////////////////////////////////////////////////////
-            new NuGetPackSettings()
-            {
-                Id = "Avalonia.Skia.Android",
-                Dependencies = new []
-                {
-                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
-                },
-                Files = new []
-                {
-                    new NuSpecContent { Source = "Avalonia.Skia.Android.dll", Target = "lib/MonoAndroid10" }
-                },
-                BasePath = context.Directory("./src/Skia/Avalonia.Skia.Android/bin/" + parameters.DirSuffix),
-                OutputDirectory = parameters.NugetRoot
-            },
-            ///////////////////////////////////////////////////////////////////////////////
             // Avalonia.iOS
             ///////////////////////////////////////////////////////////////////////////////
             new NuGetPackSettings()
@@ -279,7 +304,7 @@ public class Packages
                 Dependencies = new []
                 {
                     new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "Avalonia.Skia.iOS", Version = parameters.Version }
+                    new NuSpecDependency() { Id = "Avalonia.Skia", Version = parameters.Version }
                 },
                 Files = new []
                 {
@@ -287,42 +312,6 @@ public class Packages
                 },
                 BasePath = context.Directory("./src/iOS/Avalonia.iOS/bin/" + parameters.DirSuffixIOS),
                 OutputDirectory = parameters.NugetRoot
-            },
-            ///////////////////////////////////////////////////////////////////////////////
-            // Avalonia.Skia.iOS
-            ///////////////////////////////////////////////////////////////////////////////
-            new NuGetPackSettings()
-            {
-                Id = "Avalonia.Skia.iOS",
-                Dependencies = new []
-                {
-                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
-                },
-                Files = new []
-                {
-                    new NuSpecContent { Source = "Avalonia.Skia.iOS.dll", Target = "lib/Xamarin.iOS10" }
-                },
-                BasePath = context.Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + parameters.DirSuffixIOS),
-                OutputDirectory = parameters.NugetRoot
-            },
-            ///////////////////////////////////////////////////////////////////////////////
-            // Avalonia.Mobile
-            ///////////////////////////////////////////////////////////////////////////////
-            new NuGetPackSettings()
-            {
-                Id = "Avalonia.Mobile",
-                Dependencies = new []
-                {
-                    new NuSpecDependency() { Id = "Avalonia.Android", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "Avalonia.iOS", Version = parameters.Version }
-                },
-                Files = new NuSpecContent[]
-                {
-                    new NuSpecContent { Source = "licence.md", Target = "" }
-                },
-                BasePath = context.Directory("./"),
-                OutputDirectory = parameters.NugetRoot
             }
         };
 
@@ -341,7 +330,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 + "/netstandard1.1/Avalonia.Win32.dll", Target = "lib/netstandard1.1" }
+                    new NuSpecContent { Source = "Avalonia.Win32.NetStandard/bin/" + parameters.DirSuffix + "/netstandard2.0/Avalonia.Win32.dll", Target = "lib/netstandard2.0" }
                 },
                 BasePath = context.Directory("./src/Windows"),
                 OutputDirectory = parameters.NugetRoot
@@ -362,9 +351,9 @@ public class Packages
                 },
                 Files = new []
                 {
-                    new NuSpecContent { Source = "Avalonia.Direct2D1.dll", Target = "lib/net45" }
+                    new NuSpecContent { Source = "Avalonia.Direct2D1.dll", Target = "lib/netstandard2.0" }
                 },
-                BasePath = context.Directory("./src/Windows/Avalonia.Direct2D1/bin/" + parameters.DirSuffix),
+                BasePath = context.Directory("./src/Windows/Avalonia.Direct2D1/bin/" + parameters.DirSuffix + "/netstandard2.0"),
                 OutputDirectory = parameters.NugetRoot
             },
             ///////////////////////////////////////////////////////////////////////////////
@@ -396,9 +385,9 @@ public class Packages
                 },
                 Files = new []
                 {
-                    new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard1.1" }
+                    new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard2.0" }
                 },
-                BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard1.1"),
+                BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard2.0"),
                 OutputDirectory = parameters.NugetRoot
             },
             ///////////////////////////////////////////////////////////////////////////////
@@ -419,23 +408,27 @@ public class Packages
                 OutputDirectory = parameters.NugetRoot
             },
             ///////////////////////////////////////////////////////////////////////////////
-            // Avalonia.Skia.Desktop
+            // Avalonia.Skia
             ///////////////////////////////////////////////////////////////////////////////
             new NuGetPackSettings()
             {
-                Id = "Avalonia.Skia.Desktop",
+                Id = "Avalonia.Skia",
                 Dependencies = new []
                 {
                     new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
                     new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion },
-                    new NuSpecDependency() { Id = "Avalonia.Skia.Linux.Natives", Version = SkiaSharpLinuxVersion }
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version, TargetFramework="netcoreapp2.0" },
+                    new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion, TargetFramework="netcoreapp2.0" },
+                    new NuSpecDependency() { Id = "Avalonia.Skia.Linux.Natives", Version = SkiaSharpLinuxVersion, TargetFramework="netcoreapp2.0" },
+                    new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version, TargetFramework="net461" },
+                    new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion, TargetFramework="net461" },
+                    new NuSpecDependency() { Id = "Avalonia.Skia.Linux.Natives", Version = SkiaSharpLinuxVersion, TargetFramework="net461" }
                 },
                 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 + "/netstandard1.3/Avalonia.Skia.Desktop.dll", Target = "lib/netstandard1.3" }
+                    new NuSpecContent { Source = "Avalonia.Skia.dll", Target = "lib/netstandard2.0" }
                 },
-                BasePath = context.Directory("./src/Skia/"),
+                BasePath = context.Directory("./src/Skia/Avalonia.Skia/bin/" + parameters.DirSuffix + "/netstandard2.0"),
                 OutputDirectory = parameters.NugetRoot
             },
             ///////////////////////////////////////////////////////////////////////////////
@@ -451,12 +444,12 @@ public class Packages
                     new NuSpecDependency() { Id = "Avalonia.Gtk", TargetFramework="net45", Version = parameters.Version },
                     new NuSpecDependency() { Id = "Avalonia.Cairo", TargetFramework="net45", Version = parameters.Version },
                     new NuSpecDependency() { Id = "Avalonia.Win32", TargetFramework="net45", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", TargetFramework="net45", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Skia", TargetFramework="net45", Version = parameters.Version },
                     new NuSpecDependency() { Id = "Avalonia.Gtk3", TargetFramework="net45", Version = parameters.Version },
                     //.NET Core
-                    new NuSpecDependency() { Id = "Avalonia.Win32", TargetFramework="netcoreapp1.1", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", TargetFramework="netcoreapp1.1", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "Avalonia.Gtk3", TargetFramework="netcoreapp1.1", Version = parameters.Version }
+                    new NuSpecDependency() { Id = "Avalonia.Win32", TargetFramework="netcoreapp2.0", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Skia", TargetFramework="netcoreapp2.0", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Gtk3", TargetFramework="netcoreapp2.0", Version = parameters.Version }
                 },
                 Files = new NuSpecContent[]
                 {
@@ -465,6 +458,22 @@ public class Packages
                 BasePath = context.Directory("./"),
                 OutputDirectory = parameters.NugetRoot
             },
+            new NuGetPackSettings()
+            {
+                Id = "Avalonia.Win32.Interoperability",
+                Dependencies = new []
+                {
+                    new NuSpecDependency() { Id = "Avalonia.Win32", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "Avalonia.Direct2D1", Version = parameters.Version },
+                    new NuSpecDependency() { Id = "SharpDX.Direct3D9", Version = SharpDXDirect3D9Version },
+                },
+                Files = new []
+                {
+                    new NuSpecContent { Source = "Avalonia.Win32.Interop/bin/" + parameters.DirSuffix + "/Avalonia.Win32.Interop.dll", Target = "lib/net45" }
+                },
+                BasePath = context.Directory("./src/Windows"),
+                OutputDirectory = parameters.NugetRoot
+            },
             ///////////////////////////////////////////////////////////////////////////////
             // Avalonia.LinuxFramebuffer
             ///////////////////////////////////////////////////////////////////////////////
@@ -474,11 +483,11 @@ public class Packages
                 Dependencies = new []
                 {
                     new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
-                    new NuSpecDependency() { Id = "Avalonia.Skia.Desktop", Version = parameters.Version }
+                    new NuSpecDependency() { Id = "Avalonia.Skia", Version = parameters.Version }
                 },
                 Files = new []
                 {
-                    new NuSpecContent { Source = "Avalonia.LinuxFramebuffer/bin/" + parameters.DirSuffix + "/netstandard1.3/Avalonia.LinuxFramebuffer.dll", Target = "lib/netstandard1.3" }
+                    new NuSpecContent { Source = "Avalonia.LinuxFramebuffer/bin/" + parameters.DirSuffix + "/netstandard2.0/Avalonia.LinuxFramebuffer.dll", Target = "lib/netstandard2.0" }
                 },
                 BasePath = context.Directory("./src/Linux/"),
                 OutputDirectory = parameters.NugetRoot

+ 2 - 32
parameters.cake

@@ -32,7 +32,6 @@ public class Parameters
     public DirectoryPath BinRoot { get; private set; }
     public DirectoryPath TestsRoot { get; private set; }
     public string DirSuffix { get; private set; }
-    public string DirSuffixSkia { get; private set; }
     public string DirSuffixIOS { get; private set; }
     public DirectoryPathCollection BuildDirs { get; private set; }
     public string FileZipSuffix { get; private set; }
@@ -109,40 +108,11 @@ public class Parameters
         BinRoot = ArtifactsDir.Combine("bin");
         TestsRoot = ArtifactsDir.Combine("tests");
 
+        BuildDirs = context.GetDirectories("**/bin") + context.GetDirectories("**/obj");
+
         DirSuffix = Configuration;
-        DirSuffixSkia = (IsPlatformAnyCPU ? "x86" : Platform) + "/" + Configuration;
         DirSuffixIOS = "iPhone" + "/" + Configuration;
 
-        BuildDirs = 
-            context.GetDirectories("./src/**/bin/" + DirSuffix) + 
-            context.GetDirectories("./src/**/obj/" + DirSuffix) + 
-            context.GetDirectories("./src/Markup/**/bin/" + DirSuffix) + 
-            context.GetDirectories("./src/Markup/**/obj/" + DirSuffix) + 
-            context.GetDirectories("./src/Android/**/bin/" + DirSuffix) + 
-            context.GetDirectories("./src/Android/**/obj/" + DirSuffix) + 
-            context.GetDirectories("./src/Gtk/**/bin/" + DirSuffix) + 
-            context.GetDirectories("./src/Gtk/**/obj/" + DirSuffix) + 
-            context.GetDirectories("./src/iOS/**/bin/" + DirSuffixIOS) + 
-            context.GetDirectories("./src/iOS/**/obj/" + DirSuffixIOS) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Android/bin/" + DirSuffix) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Android/obj/" + DirSuffix) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Android.TestApp/bin/" + DirSuffix) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Android.TestApp/obj/" + DirSuffix) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Desktop/bin/" + DirSuffixSkia) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Desktop/obj/" + DirSuffixSkia) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Desktop.NetStandard/bin/" + DirSuffix) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.Desktop.NetStandard/obj/" + DirSuffix) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.iOS/bin/" + DirSuffixIOS) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.iOS/obj/" + DirSuffixIOS) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/bin/" + DirSuffixIOS) + 
-            (DirectoryPath)context.Directory("./src/Skia/Avalonia.Skia.iOS.TestApp/obj/" + DirSuffixIOS) + 
-            context.GetDirectories("./src/Windows/**/bin/" + DirSuffix) + 
-            context.GetDirectories("./src/Windows/**/obj/" + DirSuffix) + 
-            context.GetDirectories("./tests/**/bin/" + DirSuffix) + 
-            context.GetDirectories("./tests/**/obj/" + DirSuffix) + 
-            context.GetDirectories("./Samples/**/bin/" + DirSuffix) + 
-            context.GetDirectories("./Samples/**/obj/" + DirSuffix);
-
         FileZipSuffix = Version + ".zip";
         ZipCoreArtifacts = ZipRoot.CombineWithFilePath("Avalonia-" + FileZipSuffix);
         ZipSourceControlCatalogDesktopDirs = (DirectoryPath)context.Directory("./samples/ControlCatalog.Desktop/bin/" + DirSuffix);

+ 3 - 3
readme.md

@@ -1,9 +1,9 @@
 # Avalonia
 
 
-| Gitter Chat | Windows Build Status | Linux/Mac Build Status | Code Coverage |
-|---|---|---|---|
-| [![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) |
+| Gitter Chat | Windows Build Status | Linux/Mac Build Status |
+|---|---|---|
+| [![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) |
 
 A multi-platform .NET UI framework. It can run on Windows, Linux, Mac OS X, iOS and Android.
 

+ 8 - 8
samples/BindingTest/App.config

@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
     <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
     </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" />
+        <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" />
+        <assemblyIdentity name="SharpDX.DXGI" publicKeyToken="b4dcf0f35e5521f1" culture="neutral"/>
+        <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" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
+        <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral"/>
+        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0"/>
       </dependentAssembly>
     </assemblyBinding>
   </runtime>

+ 2 - 2
samples/BindingTest/BindingTest.csproj

@@ -9,7 +9,7 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>BindingTest</RootNamespace>
     <AssemblyName>BindingTest</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <TargetFrameworkProfile />
@@ -66,6 +66,7 @@
     <Compile Include="ViewModels\IndeiErrorViewModel.cs" />
     <Compile Include="ViewModels\ExceptionErrorViewModel.cs" />
     <Compile Include="ViewModels\MainWindowViewModel.cs" />
+    <Compile Include="ViewModels\NestedCommandViewModel.cs" />
     <Compile Include="ViewModels\TestItem.cs" />
   </ItemGroup>
   <ItemGroup>
@@ -162,5 +163,4 @@
   <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>

+ 4 - 1
samples/BindingTest/MainWindow.xaml

@@ -44,6 +44,8 @@
           <StackPanel Margin="18" Gap="4" Width="200" HorizontalAlignment="Left">
             <TextBlock FontSize="16" Text="Scheduler"/>
             <TextBox Watermark="Background Thread" Text="{Binding CurrentTime, Mode=OneWay}"/>
+            <TextBlock FontSize="16" Text="Stream Operator"/>
+            <TextBox Watermark="StreamOperator" Text="{Binding CurrentTimeObservable^, Mode=OneWay}"/>
           </StackPanel>
         </StackPanel>
       </StackPanel>
@@ -95,8 +97,9 @@
         <Button Content="Button" Command="{Binding StringValueCommand}" CommandParameter="Button"/>
         <ToggleButton Content="ToggleButton" IsChecked="{Binding BooleanFlag, Mode=OneWay}" Command="{Binding StringValueCommand}" CommandParameter="ToggleButton"/>
         <CheckBox Content="CheckBox" IsChecked="{Binding !BooleanFlag, Mode=OneWay}" Command="{Binding StringValueCommand}" CommandParameter="CheckBox"/>
-        <RadioButton Content="RadionButton" IsChecked="{Binding !!BooleanFlag, Mode=OneWay}" Command="{Binding StringValueCommand}" CommandParameter="RadioButton"/>
+        <RadioButton Content="Radio Button" IsChecked="{Binding !!BooleanFlag, Mode=OneWay}" Command="{Binding StringValueCommand}" CommandParameter="RadioButton"/>
         <TextBox Text="{Binding Path=StringValue}"/>
+        <Button Content="Nested View Model Button" Name="NestedTest" Command="{Binding NestedModel.Command}" />
       </StackPanel>
     </TabItem>
   </TabControl>

+ 12 - 0
samples/BindingTest/ViewModels/MainWindowViewModel.cs

@@ -15,6 +15,7 @@ namespace BindingTest.ViewModels
         private string _stringValue = "Simple Binding";
         private bool _booleanFlag = false;
         private string _currentTime;
+        private NestedCommandViewModel _nested;
 
         public MainWindowViewModel()
         {
@@ -39,6 +40,7 @@ namespace BindingTest.ViewModels
             {
                 BooleanFlag = !BooleanFlag;
                 StringValue = param.ToString();
+                NestedModel = _nested ?? new NestedCommandViewModel();
             });
 
             Task.Run(() =>
@@ -49,6 +51,9 @@ namespace BindingTest.ViewModels
                     Thread.Sleep(1000);
                 }
             });
+
+            CurrentTimeObservable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1))
+                .Select(x => DateTimeOffset.Now.ToString());
         }
 
         public ObservableCollection<TestItem> Items { get; }
@@ -85,10 +90,17 @@ namespace BindingTest.ViewModels
             private set { this.RaiseAndSetIfChanged(ref _currentTime, value); }
         }
 
+        public IObservable<string> CurrentTimeObservable { get; }
         public ReactiveCommand<object> StringValueCommand { get; }
 
         public DataAnnotationsErrorViewModel DataAnnotationsValidation { get; } = new DataAnnotationsErrorViewModel();
         public ExceptionErrorViewModel ExceptionDataValidation { get; } = new ExceptionErrorViewModel();
         public IndeiErrorViewModel IndeiDataValidation { get; } = new IndeiErrorViewModel();
+
+        public NestedCommandViewModel NestedModel
+        {
+            get { return _nested; }
+            private set { this.RaiseAndSetIfChanged(ref _nested, value); }
+        }
     }
 }

+ 20 - 0
samples/BindingTest/ViewModels/NestedCommandViewModel.cs

@@ -0,0 +1,20 @@
+using ReactiveUI;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+using System.Windows.Input;
+
+namespace BindingTest.ViewModels
+{
+    public class NestedCommandViewModel : ReactiveObject
+    {
+        public NestedCommandViewModel()
+        {
+            Command = ReactiveCommand.Create();
+        }
+
+        public ICommand Command { get; }
+    }
+}

+ 3 - 4
samples/ControlCatalog.Android/ControlCatalog.Android.csproj

@@ -147,9 +147,9 @@
       <Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
       <Name>Avalonia.Markup</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia.Android\Avalonia.Skia.Android.csproj">
-      <Project>{bd43f7c0-396b-4aa1-bad9-dfde54d51298}</Project>
-      <Name>Avalonia.Skia.Android</Name>
+    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
+      <Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
+      <Name>Avalonia.Skia</Name>
     </ProjectReference>
     <ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj">
       <Project>{d0a739b9-3c68-4ba6-a328-41606954b6bd}</Project>
@@ -158,5 +158,4 @@
   </ItemGroup>
   <Import Project="..\..\build\Rx.props" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

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

@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
     <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
     </startup>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
-        <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
+        <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" />
+        <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" />
+        <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>

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

@@ -9,7 +9,7 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>ControlCatalog.Desktop</RootNamespace>
     <AssemblyName>ControlCatalog.Desktop</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <TargetFrameworkProfile />
@@ -123,9 +123,9 @@
       <Project>{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}</Project>
       <Name>Avalonia.Themes.Default</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia.Desktop\Avalonia.Skia.Desktop.csproj" Condition="'$(Platform)'!='Mono'">
-      <Project>{925DD807-B651-475F-9F7C-CBEB974CE43D}</Project>
-      <Name>Avalonia.Skia.Desktop</Name>
+    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
+      <Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
+      <Name>Avalonia.Skia</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" Condition="'$(Platform)'!='Mono'">
       <Project>{3E908F67-5543-4879-A1DC-08EACE79B3CD}</Project>
@@ -144,5 +144,4 @@
   <Import Project="..\..\build\Serilog.props" />
   <Import Project="..\..\build\SkiaSharp.props" />
   <Import Project="..\..\build\Serilog.Sinks.Trace.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 1 - 1
samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj

@@ -2,7 +2,7 @@
 
   <PropertyGroup>
     <OutputType>Exe</OutputType>
-    <TargetFramework>netcoreapp1.1</TargetFramework>
+    <TargetFramework>netcoreapp2.0</TargetFramework>
   </PropertyGroup>
 
   <ItemGroup>

+ 3 - 4
samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj

@@ -169,9 +169,9 @@
       <Project>{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}</Project>
       <Name>Avalonia.Themes.Default</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia.iOS\Avalonia.Skia.iOS.csproj">
-      <Project>{47BE08A7-5985-410B-9FFC-2264B8EA595F}</Project>
-      <Name>Avalonia.Skia.iOS</Name>
+    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
+      <Project>{D2D3083-71DD-4CC9-8907-39A0D86FB322}</Project>
+      <Name>Avalonia.Skia</Name>
       <IsAppExtension>false</IsAppExtension>
       <IsWatchApp>false</IsWatchApp>
     </ProjectReference>
@@ -181,5 +181,4 @@
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 9 - 2
samples/ControlCatalog/ControlCatalog.csproj

@@ -1,6 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFramework>netstandard1.1</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <EnableDefaultCompileItems>False</EnableDefaultCompileItems>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
@@ -21,6 +21,9 @@
     <ErrorReport>prompt</ErrorReport>
     <WarningLevel>4</WarningLevel>
   </PropertyGroup>
+  <ItemGroup>
+    <None Remove="Pages\ContextMenuPage.xaml" />
+  </ItemGroup>
   <ItemGroup>
     <!-- A reference to the entire .NET Framework is automatically included -->
     <EmbeddedResource Include="App.xaml">
@@ -44,6 +47,7 @@
     <EmbeddedResource Include="Pages\CheckBoxPage.xaml">
       <SubType>Designer</SubType>
     </EmbeddedResource>
+    <EmbeddedResource Include="Pages\ContextMenuPage.xaml" />
     <EmbeddedResource Include="Pages\DropDownPage.xaml">
       <SubType>Designer</SubType>
     </EmbeddedResource>
@@ -94,6 +98,9 @@
     <Compile Include="Pages\CarouselPage.xaml.cs">
       <DependentUpon>CarouselPage.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Pages\ContextMenuPage.xaml.cs">
+      <DependentUpon>ContextMenuPage.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Pages\CheckBoxPage.xaml.cs">
       <DependentUpon>CheckBoxPage.xaml</DependentUpon>
     </Compile>
@@ -117,7 +124,7 @@
     </Compile>
     <Compile Include="Pages\SliderPage.xaml.cs">
       <DependentUpon>SliderPage.xaml</DependentUpon>
-    </Compile>
+    </Compile>    
     <Compile Include="Pages\TreeViewPage.xaml.cs">
       <DependentUpon>TreeViewPage.xaml</DependentUpon>
     </Compile>

+ 1 - 0
samples/ControlCatalog/MainView.xaml

@@ -10,6 +10,7 @@
     <TabItem Header="Canvas"><pages:CanvasPage/></TabItem>
     <TabItem Header="Carousel"><pages:CarouselPage/></TabItem>
     <TabItem Header="CheckBox"><pages:CheckBoxPage/></TabItem>
+    <TabItem Header="ContextMenu"><pages:ContextMenuPage/></TabItem>
     <TabItem Header="DropDown"><pages:DropDownPage/></TabItem>
     <TabItem Header="Expander"><pages:ExpanderPage/></TabItem>
     <TabItem Header="Image"><pages:ImagePage/></TabItem>

+ 3 - 1
samples/ControlCatalog/MainWindow.xaml.cs

@@ -1,6 +1,7 @@
 using Avalonia;
 using Avalonia.Controls;
 using Avalonia.Markup.Xaml;
+using System;
 
 namespace ControlCatalog
 {
@@ -10,6 +11,7 @@ namespace ControlCatalog
         {
             this.InitializeComponent();
             this.AttachDevTools();
+            Renderer.DrawDirtyRects = Renderer.DrawFps = true;
         }
 
         private void InitializeComponent()
@@ -18,7 +20,7 @@ namespace ControlCatalog
             // so we must refer to this resource DLL statically. For
             // now I am doing that here. But we need a better solution!!
             var theme = new Avalonia.Themes.Default.DefaultTheme();
-            theme.FindResource("Button");
+            theme.TryGetResource("Button", out _);
             AvaloniaXamlLoader.Load(this);
         }
     }

+ 36 - 0
samples/ControlCatalog/Pages/ContextMenuPage.xaml

@@ -0,0 +1,36 @@
+<UserControl xmlns="https://github.com/avaloniaui">
+    <StackPanel Orientation="Vertical" Gap="4">
+        <TextBlock Classes="h1">Context Menu</TextBlock>
+        <TextBlock Classes="h2">A right click menu that can be applied to any control.</TextBlock>
+
+        <StackPanel Orientation="Horizontal"
+              Margin="0,16,0,0"
+              HorizontalAlignment="Center"
+              Gap="16">
+            <Border Background="{StyleResource ThemeAccentBrush}"
+              Padding="48,48,48,48">
+                <Border.ContextMenu>
+                    <ContextMenu>
+                        <MenuItem Header="Standard _Menu Item"/>
+                        <Separator/>
+                        <MenuItem Header="Menu with _Submenu">
+                            <MenuItem Header="Submenu _1"/>
+                            <MenuItem Header="Submenu _2"/>
+                        </MenuItem>
+                        <MenuItem Header="Menu Item with _Icon">
+                            <MenuItem.Icon>
+                                <Image Source="resm:ControlCatalog.Assets.github_icon.png"/>
+                            </MenuItem.Icon>
+                        </MenuItem>
+                        <MenuItem Header="Menu Item with _Checkbox">
+                            <MenuItem.Icon>
+                                <CheckBox BorderThickness="0" IsHitTestVisible="False" IsChecked="True"/>
+                            </MenuItem.Icon>
+                        </MenuItem>
+                    </ContextMenu>
+                </Border.ContextMenu>
+                <TextBlock Text="Right Click Here"/>
+            </Border>
+        </StackPanel>
+    </StackPanel>
+</UserControl>

+ 18 - 0
samples/ControlCatalog/Pages/ContextMenuPage.xaml.cs

@@ -0,0 +1,18 @@
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace ControlCatalog.Pages
+{
+    public class ContextMenuPage : UserControl
+    {
+        public ContextMenuPage()
+        {
+            this.InitializeComponent();
+        }
+
+        private void InitializeComponent()
+        {
+            AvaloniaXamlLoader.Load(this);
+        }
+    }
+}

+ 25 - 25
samples/ControlCatalog/Pages/MenuPage.xaml

@@ -3,33 +3,33 @@
     <TextBlock Classes="h1">Menu</TextBlock>
     <TextBlock Classes="h2">A window menu</TextBlock>
 
-    <StackPanel Orientation="Horizontal"
+        <StackPanel Orientation="Horizontal"
               Margin="0,16,0,0"
               HorizontalAlignment="Center"
               Gap="16">
-      <Menu>
-        <MenuItem Header="_First">
-          <MenuItem Header="Standard _Menu Item"/>
-          <Separator/>
-          <MenuItem Header="Menu with _Submenu">
-            <MenuItem Header="Submenu _1"/>
-            <MenuItem Header="Submenu _2"/>
-          </MenuItem>
-          <MenuItem Header="Menu Item with _Icon">
-            <MenuItem.Icon>
-              <Image Source="resm:ControlCatalog.Assets.github_icon.png"/>
-            </MenuItem.Icon>
-          </MenuItem>
-          <MenuItem Header="Menu Item with _Checkbox">
-            <MenuItem.Icon>
-              <CheckBox BorderThickness="0" IsHitTestVisible="False" IsChecked="True"/>
-            </MenuItem.Icon>
-          </MenuItem>
-        </MenuItem>
-        <MenuItem Header="_Second">
-          <MenuItem Header="Second _Menu Item"/>
-        </MenuItem>
-      </Menu>
+            <Menu>
+                <MenuItem Header="_First">
+                    <MenuItem Header="Standard _Menu Item"/>
+                    <Separator/>
+                    <MenuItem Header="Menu with _Submenu">
+                        <MenuItem Header="Submenu _1"/>
+                        <MenuItem Header="Submenu _2"/>
+                    </MenuItem>
+                    <MenuItem Header="Menu Item with _Icon">
+                        <MenuItem.Icon>
+                            <Image Source="resm:ControlCatalog.Assets.github_icon.png"/>
+                        </MenuItem.Icon>
+                    </MenuItem>
+                    <MenuItem Header="Menu Item with _Checkbox">
+                        <MenuItem.Icon>
+                            <CheckBox BorderThickness="0" IsHitTestVisible="False" IsChecked="True"/>
+                        </MenuItem.Icon>
+                    </MenuItem>
+                </MenuItem>
+                <MenuItem Header="_Second">
+                    <MenuItem Header="Second _Menu Item"/>
+                </MenuItem>
+            </Menu>
+        </StackPanel>
     </StackPanel>
-  </StackPanel>
 </UserControl>

+ 36 - 17
samples/ControlCatalog/Pages/ToolTipPage.xaml

@@ -1,22 +1,41 @@
 <UserControl xmlns="https://github.com/avaloniaui">
-  <StackPanel Orientation="Vertical" Gap="4">
-    <TextBlock Classes="h1">ToolTip</TextBlock>
-    <TextBlock Classes="h2">A control which pops up a hint when a control is hovered</TextBlock>
+    <StackPanel Orientation="Vertical"
+                Gap="4">
+        <TextBlock Classes="h1">ToolTip</TextBlock>
+        <TextBlock Classes="h2">A control which pops up a hint when a control is hovered</TextBlock>
 
-    <StackPanel Orientation="Horizontal"
+        <Grid RowDefinitions="Auto,Auto"
+              ColumnDefinitions="Auto,Auto"
               Margin="0,16,0,0"
-              HorizontalAlignment="Center"
-              Gap="16">
-      <Border Background="{StyleResource ThemeAccentBrush}"
-              Padding="48,48,48,48">
-        <ToolTip.Tip>
-          <StackPanel>
-            <TextBlock Classes="h1">ToolTip</TextBlock>
-            <TextBlock Classes="h2">A control which pops up a hint when a control is hovered</TextBlock>
-          </StackPanel>
-        </ToolTip.Tip>
-        <TextBlock>Hover Here</TextBlock>
-      </Border>
+              HorizontalAlignment="Center">
+            <Border Grid.Column="0"
+                    Grid.Row="1"
+                    Background="{StyleResource ThemeAccentBrush}"
+                    Margin="5"
+                    Padding="50"
+                    ToolTip.Tip="This is a ToolTip">
+                <TextBlock>Hover Here</TextBlock>
+            </Border>
+            <CheckBox Grid.Column="1"
+                      Margin="5"
+                      Grid.Row="0"
+                      IsChecked="{Binding ElementName=Border, Path=(ToolTip.IsOpen)}"
+                      Content="ToolTip Open" />
+            <Border Name="Border"
+                    Grid.Column="1"
+                    Grid.Row="1"
+                    Background="{StyleResource ThemeAccentBrush}"
+                    Margin="5"
+                    Padding="50"
+                    ToolTip.Placement="Bottom">
+                <ToolTip.Tip>
+                    <StackPanel>
+                        <TextBlock Classes="h1">ToolTip</TextBlock>
+                        <TextBlock Classes="h2">A control which pops up a hint when a control is hovered</TextBlock>
+                    </StackPanel>
+                </ToolTip.Tip>
+                <TextBlock>ToolTip bottom placement</TextBlock>
+            </Border>
+        </Grid>
     </StackPanel>
-  </StackPanel>
 </UserControl>

+ 8 - 8
samples/RenderTest/App.config

@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
     <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
     </startup>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
-        <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
+        <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" />
+        <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" />
+        <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>

+ 1 - 0
samples/RenderTest/MainWindow.xaml

@@ -27,6 +27,7 @@
       </TabControl.Transition>
       <TabItem Header="Animations"><pages:AnimationsPage/></TabItem>
       <TabItem Header="Clipping"><pages:ClippingPage/></TabItem>
+      <TabItem Header="Drawing"><pages:DrawingPage/></TabItem>
     </TabControl>
   </DockPanel>
 </Window>

+ 132 - 0
samples/RenderTest/Pages/DrawingPage.xaml

@@ -0,0 +1,132 @@
+<UserControl xmlns="https://github.com/avaloniaui"
+             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
+    <UserControl.Styles>
+        <Style>
+            <Style.Resources>
+                <DrawingGroup x:Key="Bulb">
+                    <DrawingGroup.Transform>
+                        <MatrixTransform Matrix="1,0,0,1,0,-1028.4" />
+                    </DrawingGroup.Transform>
+                    <DrawingGroup>
+                        <DrawingGroup.Transform>
+                            <MatrixTransform Matrix="1,0,0,1.25,-10,1031.4" />
+                        </DrawingGroup.Transform>
+                        <GeometryDrawing Brush="#FF7F8C8D"
+                                         Geometry="F1 M24,14 A2,2,0,1,1,20,14 A2,2,0,1,1,24,14 z" />
+                    </DrawingGroup>
+                    <GeometryDrawing Brush="#FFF39C12"
+                                     Geometry="F1 M12,1030.4 C8.134,1030.4 5,1033.6 5,1037.6 5,1040.7 8.125,1043.5 9,1045.4 9.875,1047.2 9,1050.4 9,1050.4 L12,1049.9 15,1050.4 C15,1050.4 14.125,1047.2 15,1045.4 15.875,1043.5 19,1040.7 19,1037.6 19,1033.6 15.866,1030.4 12,1030.4 z" />
+                    <GeometryDrawing Brush="#FFF1C40F"
+                                     Geometry="F1 M12,1030.4 C15.866,1030.4 19,1033.6 19,1037.6 19,1040.7 15.875,1043.5 15,1045.4 14.125,1047.2 15,1050.4 15,1050.4 L12,1049.9 12,1030.4 z" />
+                    <GeometryDrawing Brush="#FFE67E22"
+                                     Geometry="F1 M9,1036.4 L8,1037.4 12,1049.4 16,1037.4 15,1036.4 14,1037.4 13,1036.4 12,1037.4 11,1036.4 10,1037.4 9,1036.4 z M9,1037.4 L10,1038.4 10.5,1037.9 11,1037.4 11.5,1037.9 12,1038.4 12.5,1037.9 13,1037.4 13.5,1037.9 14,1038.4 15,1037.4 15.438,1037.8 12,1048.1 8.5625,1037.8 9,1037.4 z" />
+                    <DrawingGroup>
+                        <DrawingGroup.Transform>
+                            <MatrixTransform Matrix="1,0,0,1,9,1045.4" />
+                        </DrawingGroup.Transform>
+                        <GeometryDrawing Brush="#FFBDC3C7">
+                            <GeometryDrawing.Geometry>
+                                <RectangleGeometry Rect="0,0,6,5" />
+                            </GeometryDrawing.Geometry>
+                        </GeometryDrawing>
+                    </DrawingGroup>
+                    <GeometryDrawing Brush="#FF95A5A6"
+                                     Geometry="F1 M9,1045.4 L9,1050.4 12,1050.4 12,1049.4 15,1049.4 15,1048.4 12,1048.4 12,1047.4 15,1047.4 15,1046.4 12,1046.4 12,1045.4 9,1045.4 z" />
+                    <GeometryDrawing Brush="#FF7F8C8D"
+                                     Geometry="F1 M9,1046.4 L9,1047.4 12,1047.4 12,1046.4 9,1046.4 z M9,1048.4 L9,1049.4 12,1049.4 12,1048.4 9,1048.4 z" />
+                </DrawingGroup>
+            </Style.Resources>
+        </Style>
+    </UserControl.Styles>
+    <Grid RowDefinitions="Auto,Auto,Auto"
+          ColumnDefinitions="Auto,Auto,Auto,Auto">
+        <TextBlock Text="None"
+                   Margin="3" />
+        <Border Grid.Column="0"
+                Grid.Row="1"
+                VerticalAlignment="Top"
+                HorizontalAlignment="Left"
+                BorderThickness="1"
+                BorderBrush="Gray"
+                Margin="5">
+            <DrawingPresenter Drawing="{StyleResource Bulb}" />
+        </Border>
+        <TextBlock Text="Fill"
+                   Margin="3"
+                   Grid.Column="1" />
+        <Border Grid.Column="1"
+                Grid.Row="1"
+                VerticalAlignment="Top"
+                HorizontalAlignment="Left"
+                BorderThickness="1"
+                BorderBrush="Gray"
+                Margin="5">
+            <DrawingPresenter Drawing="{StyleResource Bulb}"
+                              Width="100"
+                              Height="50"
+                              Stretch="Fill" />
+        </Border>
+        <TextBlock Text="Uniform"
+                   Margin="3"
+                   Grid.Column="2" />
+        <Border Grid.Column="2"
+                Grid.Row="1"
+                VerticalAlignment="Top"
+                HorizontalAlignment="Left"
+                BorderThickness="1"
+                BorderBrush="Gray"
+                Margin="5">
+            <DrawingPresenter Drawing="{StyleResource Bulb}"
+                              Width="100"
+                              Height="50"
+                              Stretch="Uniform" />
+        </Border>
+        <TextBlock Text="UniformToFill"
+                   Margin="3"
+                   Grid.Column="3" />
+        <Border Grid.Column="3"
+                Grid.Row="1"
+                VerticalAlignment="Top"
+                HorizontalAlignment="Left"
+                BorderThickness="1"
+                BorderBrush="Gray"
+                Margin="5">
+            <DrawingPresenter Drawing="{StyleResource Bulb}"
+                              Width="100"
+                              Height="50"
+                              Stretch="UniformToFill" />
+        </Border>
+
+        <!-- For comparison -->
+        
+        <Ellipse Grid.Row="2"
+                 Grid.Column="0"
+                 Width="100"
+                 Height="50"
+                 Stretch="None"
+                 Fill="Blue"
+                 Margin="5"/>
+        <Ellipse Grid.Row="2"
+                 Grid.Column="1"
+                 Width="100"
+                 Height="50"
+                 Stretch="Fill"
+                 Fill="Blue"
+                 Margin="5" />
+        <Ellipse Grid.Row="2"
+                 Grid.Column="2"
+                 Width="100"
+                 Height="50"
+                 Stretch="Uniform"
+                 Fill="Blue"
+                 Margin="5" />
+        <Ellipse Grid.Row="2"
+                 Grid.Column="3"
+                 Width="100"
+                 Height="50"
+                 Stretch="UniformToFill"
+                 Fill="Blue"
+                 Margin="5" />
+        
+    </Grid>
+</UserControl>

+ 18 - 0
samples/RenderTest/Pages/DrawingPage.xaml.cs

@@ -0,0 +1,18 @@
+using Avalonia.Controls;
+using Avalonia.Markup.Xaml;
+
+namespace RenderTest.Pages
+{
+    public class DrawingPage : UserControl
+    {
+        public DrawingPage()
+        {
+            InitializeComponent();
+        }
+
+        private void InitializeComponent()
+        {
+            AvaloniaXamlLoader.Load(this);
+        }
+    }
+}

+ 12 - 5
samples/RenderTest/RenderTest.csproj

@@ -9,7 +9,7 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>RenderTest</RootNamespace>
     <AssemblyName>RenderTest</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <TargetFrameworkProfile />
@@ -51,6 +51,9 @@
     <Compile Include="App.xaml.cs">
       <DependentUpon>App.xaml</DependentUpon>
     </Compile>
+    <Compile Include="Pages\DrawingPage.xaml.cs">
+      <DependentUpon>DrawingPage.xaml</DependentUpon>
+    </Compile>
     <Compile Include="Pages\ClippingPage.xaml.cs">
       <DependentUpon>ClippingPage.xaml</DependentUpon>
     </Compile>
@@ -145,9 +148,9 @@
       <Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
       <Name>Avalonia.Markup</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia.Desktop\Avalonia.Skia.Desktop.csproj">
-      <Project>{925dd807-b651-475f-9f7c-cbeb974ce43d}</Project>
-      <Name>Avalonia.Skia.Desktop</Name>
+    <ProjectReference Include="..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
+      <Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
+      <Name>Avalonia.Skia</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj">
       <Project>{3e908f67-5543-4879-a1dc-08eace79b3cd}</Project>
@@ -178,10 +181,14 @@
       <SubType>Designer</SubType>
     </EmbeddedResource>
   </ItemGroup>
+  <ItemGroup>
+    <EmbeddedResource Include="Pages\DrawingPage.xaml">
+      <SubType>Designer</SubType>
+    </EmbeddedResource>
+  </ItemGroup>
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
   <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>

+ 8 - 8
samples/VirtualizationTest/App.config

@@ -1,21 +1,21 @@
-<?xml version="1.0" encoding="utf-8"?>
+<?xml version="1.0" encoding="utf-8"?>
 <configuration>
     <startup> 
-        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.5" />
+        <supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6.1"/>
     </startup>
   <runtime>
     <assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
       <dependentAssembly>
-        <assemblyIdentity name="Mono.Cairo" publicKeyToken="0738eb9f132ed756" culture="neutral" />
-        <bindingRedirect oldVersion="0.0.0.0-4.0.0.0" newVersion="4.0.0.0" />
+        <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" />
+        <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" />
+        <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>

+ 1 - 2
samples/VirtualizationTest/VirtualizationTest.csproj

@@ -9,7 +9,7 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>VirtualizationTest</RootNamespace>
     <AssemblyName>VirtualizationTest</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
     <TargetFrameworkProfile />
@@ -158,5 +158,4 @@
   <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>

+ 3 - 3
samples/interop/Direct3DInteropSample/Direct3DInteropSample.csproj

@@ -4,8 +4,8 @@
         <TargetFramework>net461</TargetFramework>
     </PropertyGroup>
     <ItemGroup>
-        <PackageReference Include="SharpDX.Mathematics" Version="3.1.1" />
-        <PackageReference Include="SharpDX.D3DCompiler" Version="3.1.1" />
+        <PackageReference Include="SharpDX.Mathematics" Version="4.0.1" />
+        <PackageReference Include="SharpDX.D3DCompiler" Version="4.0.1" />
         <Compile Update="**\*.paml.cs">
             <DependentUpon>%(Filename)</DependentUpon>
         </Compile>
@@ -22,6 +22,7 @@
     <ItemGroup>
         <ProjectReference Include="..\..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" />
         <ProjectReference Include="..\..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj" />
+        <ProjectReference Include="..\..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.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" />
@@ -30,5 +31,4 @@
     <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>

+ 1 - 1
samples/interop/Direct3DInteropSample/Program.cs

@@ -11,7 +11,7 @@ namespace Direct3DInteropSample
     {
         static void Main(string[] args)
         {
-            AppBuilder.Configure<App>().UseWin32().UseDirect2D1().Start<MainWindow>();
+            AppBuilder.Configure<App>().UseWin32(deferredRendering: false).UseDirect2D1().Start<MainWindow>();
         }
     }
 }

+ 4 - 5
samples/interop/GtkInteropDemo/GtkInteropDemo.csproj

@@ -9,7 +9,7 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>GtkInteropDemo</RootNamespace>
     <AssemblyName>GtkInteropDemo</AssemblyName>
-    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
   </PropertyGroup>
@@ -140,9 +140,9 @@
       <Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
       <Name>Avalonia.Markup</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\..\src\Skia\Avalonia.Skia.Desktop\Avalonia.Skia.Desktop.csproj">
-      <Project>{925dd807-b651-475f-9f7c-cbeb974ce43d}</Project>
-      <Name>Avalonia.Skia.Desktop</Name>
+    <ProjectReference Include="..\..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
+      <Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
+      <Name>Avalonia.Skia</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\ControlCatalog\ControlCatalog.csproj">
       <Project>{d0a739b9-3c68-4ba6-a328-41606954b6bd}</Project>
@@ -151,5 +151,4 @@
   </ItemGroup>
   <Import Project="..\..\..\build\Rx.props" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\..\src\Shared\nuget.workaround.targets" />
 </Project>

+ 13 - 1
samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml

@@ -1,10 +1,12 @@
 <Window x:Class="WindowsInteropTest.EmbedToWpfDemo"
              xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
              xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
+             xmlns:av="clr-namespace:Avalonia.Controls;assembly=Avalonia.Controls"
              xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
              xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
              xmlns:local="clr-namespace:WindowsInteropTest"
              xmlns:embedding="clr-namespace:Avalonia.Win32.Embedding;assembly=Avalonia.Win32"
+             xmlns:wpf="clr-namespace:Avalonia.Win32.Interop.Wpf;assembly=Avalonia.Win32.Interop"
              mc:Ignorable="d" 
              d:DesignHeight="400" d:DesignWidth="400" MinWidth="500" MinHeight="400">
     <DockPanel>
@@ -14,8 +16,18 @@
                 <Calendar/>
             </StackPanel>
         </GroupBox>
+        <GroupBox Header="Avalonia button" DockPanel.Dock="Bottom">
+            <wpf:WpfAvaloniaHost >
+                <av:Button Content="Avalonia button"/>
+            </wpf:WpfAvaloniaHost>
+        </GroupBox>
+        <GroupBox Header="AvBtn" DockPanel.Dock="Right">
+            <wpf:WpfAvaloniaHost x:Name="RightBtn">
+                <av:Button Content="Avalonia button 2"/>
+            </wpf:WpfAvaloniaHost>
+        </GroupBox>
         <GroupBox Header="Avalonia">
-            <embedding:WpfAvaloniaControlHost x:Name="Host"/>
+            <wpf:WpfAvaloniaHost x:Name="Host"/>
         </GroupBox>
     </DockPanel>
 </Window>

+ 14 - 1
samples/interop/WindowsInteropTest/EmbedToWpfDemo.xaml.cs

@@ -11,7 +11,9 @@ using System.Windows.Media;
 using System.Windows.Media.Imaging;
 using System.Windows.Navigation;
 using System.Windows.Shapes;
+using Avalonia;
 using Avalonia.Controls;
+using Avalonia.VisualTree;
 using ControlCatalog;
 using Window = System.Windows.Window;
 
@@ -25,7 +27,18 @@ namespace WindowsInteropTest
         public EmbedToWpfDemo()
         {
             InitializeComponent();
-            Host.Content =  new MainView();
+            var view = new MainView();
+            view.AttachedToVisualTree += delegate
+            {
+                ((TopLevel) view.GetVisualRoot()).AttachDevTools(); 
+            };
+            Host.Content = view;
+            var btn = (Avalonia.Controls.Button) RightBtn.Content;
+            btn.Click += delegate
+            {
+                btn.Content += "!";
+            };
+
         }
     }
 }

+ 1 - 1
samples/interop/WindowsInteropTest/Program.cs

@@ -15,7 +15,7 @@ namespace WindowsInteropTest
         {
             System.Windows.Forms.Application.EnableVisualStyles();
             System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);
-            AppBuilder.Configure<App>().UseWin32().UseSkia().SetupWithoutStarting();
+            AppBuilder.Configure<App>().UseWin32().UseDirect2D1().SetupWithoutStarting();
             System.Windows.Forms.Application.Run(new SelectorForm());
         }
     }

+ 10 - 6
samples/interop/WindowsInteropTest/WindowsInteropTest.csproj

@@ -9,12 +9,12 @@
     <AppDesignerFolder>Properties</AppDesignerFolder>
     <RootNamespace>WindowsInteropTest</RootNamespace>
     <AssemblyName>WindowsInteropTest</AssemblyName>
-    <TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
+    <TargetFrameworkVersion>v4.6.1</TargetFrameworkVersion>
     <FileAlignment>512</FileAlignment>
     <AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <PlatformTarget>AnyCPU</PlatformTarget>
+    <PlatformTarget>x86</PlatformTarget>
     <DebugSymbols>true</DebugSymbols>
     <DebugType>full</DebugType>
     <Optimize>false</Optimize>
@@ -156,14 +156,18 @@
       <Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
       <Name>Avalonia.Markup</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\..\src\Skia\Avalonia.Skia.Desktop\Avalonia.Skia.Desktop.csproj">
-      <Project>{925dd807-b651-475f-9f7c-cbeb974ce43d}</Project>
-      <Name>Avalonia.Skia.Desktop</Name>
+    <ProjectReference Include="..\..\..\src\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
+      <Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
+      <Name>Avalonia.Skia</Name>
     </ProjectReference>
     <ProjectReference Include="..\..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj">
       <Project>{3e908f67-5543-4879-a1dc-08eace79b3cd}</Project>
       <Name>Avalonia.Direct2D1</Name>
     </ProjectReference>
+    <ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32.Interop\Avalonia.Win32.Interop.csproj">
+      <Project>{cbc4ff2f-92d4-420b-be21-9fe0b930b04e}</Project>
+      <Name>Avalonia.Win32.Interop</Name>
+    </ProjectReference>
     <ProjectReference Include="..\..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj">
       <Project>{811a76cf-1cf6-440f-963b-bbe31bd72a82}</Project>
       <Name>Avalonia.Win32</Name>
@@ -181,5 +185,5 @@
   </ItemGroup>
   <Import Project="..\..\..\build\Rx.props" />
   <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\..\src\Shared\nuget.workaround.targets" />
+  <Import Project="..\..\..\build\SkiaSharp.props" />
 </Project>

+ 5 - 0
scripts/ReplaceNugetCache.ps1

@@ -0,0 +1,5 @@
+copy ..\samples\ControlCatalog.NetCore\bin\Debug\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp1.0\
+copy ..\samples\ControlCatalog.NetCore.\bin\Debug\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard1.3\
+copy ..\samples\ControlCatalog.NetCore.\bin\Debug\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia.gtk3\$args\lib\netstandard1.3\
+copy ..\samples\ControlCatalog.NetCore.\bin\Debug\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia.skia.desktop\$args\lib\netstandard1.3\
+copy ..\samples\ControlCatalog.NetCore.\bin\Debug\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard1.3\

+ 7 - 0
scripts/ReplaceNugetCache.sh

@@ -0,0 +1,7 @@
+ #!/usr/bin/env bash
+ 
+ cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp1.1/Avalonia**.dll ~/.nuget/packages/avalonia/$1/lib/netcoreapp1.0/
+ cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp1.1/Avalonia**.dll ~/.nuget/packages/avalonia/$1/lib/netstandard1.1/
+ cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp1.1/Avalonia**.dll ~/.nuget/packages/avalonia.gtk3/$1/lib/netstandard1.1/
+ cp ../samples/ControlCatalog.NetCore/bin/Debug/netcoreapp1.1/Avalonia**.dll ~/.nuget/packages/avalonia.skia.desktop/$1/lib/netstandard1.3/
+ 

+ 5 - 0
scripts/ReplaceNugetCacheRelease.ps1

@@ -0,0 +1,5 @@
+copy ..\samples\ControlCatalog.NetCore\bin\Release\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netcoreapp1.0\
+copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia\$args\lib\netstandard1.3\
+copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia.gtk3\$args\lib\netstandard1.3\
+copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia.skia.desktop\$args\lib\netstandard1.3\
+copy ..\samples\ControlCatalog.NetCore.\bin\Release\netcoreapp1.1\Avalonia**.dll ~\.nuget\packages\avalonia.win32\$args\lib\netstandard1.3\

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

@@ -51,15 +51,12 @@ namespace Avalonia.Android
                 .Bind<IClipboard>().ToTransient<ClipboardImpl>()
                 .Bind<IStandardCursorFactory>().ToTransient<CursorFactory>()
                 .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)
                 .Bind<IPlatformIconLoader>().ToSingleton<PlatformIconLoader>()
                 .Bind<IRenderLoop>().ToConstant(new DefaultRenderLoop(60))
-
                 .Bind<IAssetLoader>().ToConstant(new AssetLoader(app.GetType().Assembly));
 
             SkiaPlatform.Initialize();

+ 3 - 7
src/Android/Avalonia.Android/Avalonia.Android.csproj

@@ -124,17 +124,13 @@
       <Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
       <Name>Avalonia.Styling</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\Skia\Avalonia.Skia.Android\Avalonia.Skia.Android.csproj">
-      <Project>{bd43f7c0-396b-4aa1-bad9-dfde54d51298}</Project>
-      <Name>Avalonia.Skia.Android</Name>
+    <ProjectReference Include="..\..\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
+      <Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
+      <Name>Avalonia.Skia</Name>
     </ProjectReference>
   </ItemGroup>
   <ItemGroup />
   <Import Project="..\..\Shared\PlatformSupport\PlatformSupport.projitems" Label="Shared" />
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
   <Import Project="..\..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
-  <PropertyGroup Condition="'$(UseRoslynPathHack)' == ''">
-    <CscToolPath>$(MSBuildToolsPath)\Roslyn</CscToolPath>
-  </PropertyGroup>
 </Project>

+ 2 - 0
src/Android/Avalonia.Android/Platform/Input/AndroidMouseDevice.cs

@@ -4,6 +4,8 @@ namespace Avalonia.Android.Platform.Input
 {
     public class AndroidMouseDevice : MouseDevice
     {
+        public static AndroidMouseDevice Instance { get; } = new AndroidMouseDevice();
+
         public AndroidMouseDevice()
         {
 

+ 1 - 1
src/Android/Avalonia.Android/Platform/SkiaPlatform/AndroidFramebuffer.cs

@@ -44,7 +44,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
         public int Width { get; }
         public int Height { get; }
         public int RowBytes { get; }
-        public Size Dpi { get; } = new Size(96, 96);
+        public Vector Dpi { get; } = new Vector(96, 96);
         public PixelFormat Format { get; }
 
         [DllImport("android")]

+ 10 - 1
src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs

@@ -10,8 +10,10 @@ using Avalonia.Platform;
 using System;
 using System.Collections.Generic;
 using System.Reactive.Disposables;
+using Avalonia.Android.Platform.Input;
 using Avalonia.Controls;
 using Avalonia.Controls.Platform.Surfaces;
+using Avalonia.Rendering;
 
 namespace Avalonia.Android.Platform.SkiaPlatform
 {
@@ -65,6 +67,8 @@ namespace Avalonia.Android.Platform.SkiaPlatform
             }
         }
 
+        public IMouseDevice MouseDevice => AndroidMouseDevice.Instance;
+
         public Action Closed { get; set; }
 
         public Action<RawInputEventArgs> Input { get; set; }
@@ -82,7 +86,12 @@ namespace Avalonia.Android.Platform.SkiaPlatform
         public IPlatformHandle Handle => _view;
 
         public IEnumerable<object> Surfaces => new object[] {this};
-        
+
+        public IRenderer CreateRenderer(IRenderRoot root)
+        {
+            return new ImmediateRenderer(root);
+        }
+
         public virtual void Hide()
         {
             _view.Visibility = ViewStates.Invisible;

+ 1 - 1
src/Android/Avalonia.Android/Platform/Specific/Helpers/AndroidTouchEventsHelper.cs

@@ -71,7 +71,7 @@ namespace Avalonia.Android.Platform.Specific.Helpers
                 if (x <= _point.X && r >= _point.X && y <= _point.Y && b >= _point.Y)
                 {
                     var inputRoot = _getInputRoot();
-                    var mouseDevice = MouseDevice.Instance;
+                    var mouseDevice = Avalonia.Android.Platform.Input.AndroidMouseDevice.Instance;
 
                     //in order the controls to work in a predictable way
                     //we need to generate mouse move before first mouse down event

+ 3 - 4
src/Android/Avalonia.AndroidTestApplication/Avalonia.AndroidTestApplication.csproj

@@ -147,9 +147,9 @@
       <Project>{5fb2b005-0a7f-4dad-add4-3ed01444e63d}</Project>
       <Name>Avalonia.HtmlRenderer</Name>
     </ProjectReference>
-    <ProjectReference Include="..\..\Skia\Avalonia.Skia.Android\Avalonia.Skia.Android.csproj">
-      <Project>{bd43f7c0-396b-4aa1-bad9-dfde54d51298}</Project>
-      <Name>Avalonia.Skia.Android</Name>
+    <ProjectReference Include="..\..\Skia\Avalonia.Skia\Avalonia.Skia.csproj">
+      <Project>{7d2d3083-71dd-4cc9-8907-39a0d86fb322}</Project>
+      <Name>Avalonia.Skia</Name>
     </ProjectReference>
   </ItemGroup>
   <Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
@@ -157,5 +157,4 @@
   <Import Project="..\..\..\build\Splat.props" />
   <Import Project="..\..\..\build\Sprache.props" />
   <Import Project="..\..\..\build\Rx.props" />
-  <Import Project="$(MSBuildThisFileDirectory)..\..\Shared\nuget.workaround.targets" />
 </Project>

+ 1 - 1
src/Avalonia.Animation/Avalonia.Animation.csproj

@@ -1,6 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFramework>netstandard1.1</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

+ 3 - 1
src/Avalonia.Base/Avalonia.Base.csproj

@@ -1,7 +1,8 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFramework>netstandard1.1</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
+    <RootNamespace>Avalonia</RootNamespace>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">
     <DebugSymbols>true</DebugSymbols>
@@ -30,6 +31,7 @@
       <Link>Properties\SharedAssemblyInfo.cs</Link>
     </Compile>
   </ItemGroup>
+  <Import Project="..\..\build\Base.props" />
   <Import Project="..\..\build\Rx.props" />
   <Import Project="..\..\build\JetBrains.Annotations.props" />
 </Project>

+ 3 - 16
src/Avalonia.Base/AvaloniaObject.cs

@@ -664,24 +664,11 @@ namespace Avalonia
 
             if (notification != null)
             {
-                if (notification.ErrorType == BindingErrorType.Error)
-                {
-                    Logger.Error(
-                        LogArea.Binding,
-                        this,
-                        "Error in binding to {Target}.{Property}: {Message}",
-                        this,
-                        property,
-                        ExceptionUtilities.GetMessage(notification.Error));
-                }
-
-                if (notification.HasValue)
-                {
-                    value = notification.Value;
-                }
+                notification.LogIfError(this, property);
+                value = notification.Value;
             }
 
-            if (notification == null || notification.HasValue)
+            if (notification == null || notification.ErrorType == BindingErrorType.Error || notification.HasValue)
             {
                 var metadata = (IDirectPropertyMetadata)property.GetMetadata(GetType());
                 var accessor = (IDirectPropertyAccessor)GetRegistered(property);

+ 3 - 0
src/Avalonia.Base/AvaloniaPropertyRegistry.cs

@@ -47,6 +47,9 @@ namespace Avalonia
         {
             Dictionary<int, AvaloniaProperty> inner;
 
+            // Ensure the type's static ctor has been run.
+            RuntimeHelpers.RunClassConstructor(ownerType.TypeHandle);
+
             if (_attached.TryGetValue(ownerType, out inner))
             {
                 return inner.Values;

+ 34 - 20
src/Avalonia.Base/Collections/AvaloniaDictionary.cs

@@ -16,6 +16,7 @@ namespace Avalonia.Collections
     /// <typeparam name="TKey">The type of the dictionary key.</typeparam>
     /// <typeparam name="TValue">The type of the dictionary value.</typeparam>
     public class AvaloniaDictionary<TKey, TValue> : IDictionary<TKey, TValue>,
+        IDictionary,
         INotifyCollectionChanged,
         INotifyPropertyChanged
     {
@@ -51,6 +52,16 @@ namespace Avalonia.Collections
         /// <inheritdoc/>
         public ICollection<TValue> Values => _inner.Values;
 
+        bool IDictionary.IsFixedSize => ((IDictionary)_inner).IsFixedSize;
+
+        ICollection IDictionary.Keys => ((IDictionary)_inner).Keys;
+
+        ICollection IDictionary.Values => ((IDictionary)_inner).Values;
+
+        bool ICollection.IsSynchronized => ((IDictionary)_inner).IsSynchronized;
+
+        object ICollection.SyncRoot => ((IDictionary)_inner).SyncRoot;
+
         /// <summary>
         /// Gets or sets the named resource.
         /// </summary>
@@ -89,6 +100,8 @@ namespace Avalonia.Collections
             }
         }
 
+        object IDictionary.this[object key] { get => ((IDictionary)_inner)[key]; set => ((IDictionary)_inner)[key] = value; }
+
         /// <inheritdoc/>
         public void Add(TKey key, TValue value)
         {
@@ -118,10 +131,7 @@ namespace Avalonia.Collections
         }
 
         /// <inheritdoc/>
-        public bool ContainsKey(TKey key)
-        {
-            return _inner.ContainsKey(key);
-        }
+        public bool ContainsKey(TKey key) => _inner.ContainsKey(key);
 
         /// <inheritdoc/>
         public void CopyTo(KeyValuePair<TKey, TValue>[] array, int arrayIndex)
@@ -130,21 +140,16 @@ namespace Avalonia.Collections
         }
 
         /// <inheritdoc/>
-        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator()
-        {
-            return _inner.GetEnumerator();
-        }
+        public IEnumerator<KeyValuePair<TKey, TValue>> GetEnumerator() => _inner.GetEnumerator();
 
         /// <inheritdoc/>
         public bool Remove(TKey key)
         {
-            TValue value;
-
-            if (_inner.TryGetValue(key, out value))
+            if (_inner.TryGetValue(key, out TValue value))
             {
                 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Count"));
                 PropertyChanged?.Invoke(this, new PropertyChangedEventArgs($"Item[{key}]"));
-                
+
                 if (CollectionChanged != null)
                 {
                     var e = new NotifyCollectionChangedEventArgs(
@@ -163,16 +168,13 @@ namespace Avalonia.Collections
         }
 
         /// <inheritdoc/>
-        public bool TryGetValue(TKey key, out TValue value)
-        {
-            return _inner.TryGetValue(key, out value);
-        }
+        public bool TryGetValue(TKey key, out TValue value) => _inner.TryGetValue(key, out value);
 
         /// <inheritdoc/>
-        IEnumerator IEnumerable.GetEnumerator()
-        {
-            return _inner.GetEnumerator();
-        }
+        IEnumerator IEnumerable.GetEnumerator() => _inner.GetEnumerator();
+
+        /// <inheritdoc/>
+        void ICollection.CopyTo(Array array, int index) => ((ICollection)_inner).CopyTo(array, index);
 
         /// <inheritdoc/>
         void ICollection<KeyValuePair<TKey, TValue>>.Add(KeyValuePair<TKey, TValue> item)
@@ -192,6 +194,18 @@ namespace Avalonia.Collections
             return Remove(item.Key);
         }
 
+        /// <inheritdoc/>
+        void IDictionary.Add(object key, object value) => Add((TKey)key, (TValue)value);
+
+        /// <inheritdoc/>
+        bool IDictionary.Contains(object key) => ((IDictionary) _inner).Contains(key);
+
+        /// <inheritdoc/>
+        IDictionaryEnumerator IDictionary.GetEnumerator() => ((IDictionary)_inner).GetEnumerator();
+
+        /// <inheritdoc/>
+        void IDictionary.Remove(object key) => Remove((TKey)key);
+
         private void NotifyAdd(TKey key, TValue value)
         {
             PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("Count"));

+ 1 - 1
src/Avalonia.Base/Collections/AvaloniaList.cs

@@ -220,7 +220,7 @@ namespace Avalonia.Collections
         /// <summary>
         /// Removes all items from the collection.
         /// </summary>
-        public void Clear()
+        public virtual void Clear()
         {
             if (this.Count > 0)
             {

+ 33 - 90
src/Avalonia.Base/Collections/AvaloniaListExtensions.cs

@@ -2,6 +2,7 @@
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
 using System;
+using System.Collections;
 using System.Collections.Generic;
 using System.Collections.Specialized;
 using System.ComponentModel;
@@ -59,7 +60,8 @@ namespace Avalonia.Collections
         /// the index in the collection and the item.
         /// </param>
         /// <param name="reset">
-        /// An action called when the collection is reset.
+        /// An action called when the collection is reset. This will be followed by calls to 
+        /// <paramref name="added"/> for each item present in the collection after the reset.
         /// </param>
         /// <returns>A disposable used to terminate the subscription.</returns>
         public static IDisposable ForEachItem<T>(
@@ -68,112 +70,38 @@ namespace Avalonia.Collections
             Action<int, T> removed,
             Action reset)
         {
-            int index;
-
-            NotifyCollectionChangedEventHandler handler = (_, e) =>
+            void Add(int index, IList items)
             {
-                switch (e.Action)
+                foreach (T item in items)
                 {
-                    case NotifyCollectionChangedAction.Add:
-                        index = e.NewStartingIndex;
-
-                        foreach (T item in e.NewItems)
-                        {
-                            added(index++, item);
-                        }
-
-                        break;
-
-                    case NotifyCollectionChangedAction.Replace:
-                        index = e.OldStartingIndex;
-
-                        foreach (T item in e.OldItems)
-                        {
-                            removed(index++, item);
-                        }
-
-                        index = e.NewStartingIndex;
-
-                        foreach (T item in e.NewItems)
-                        {
-                            added(index++, item);
-                        }
-
-                        break;
-
-                    case NotifyCollectionChangedAction.Remove:
-                        index = e.OldStartingIndex;
-
-                        foreach (T item in e.OldItems)
-                        {
-                            removed(index++, item);
-                        }
-
-                        break;
-
-                    case NotifyCollectionChangedAction.Reset:
-                        if (reset == null)
-                        {
-                            throw new InvalidOperationException(
-                                "Reset called on collection without reset handler.");
-                        }
-
-                        reset();
-                        break;
+                    added(index++, item);
                 }
-            };
+            }
 
-            index = 0;
-            foreach (T i in collection)
+            void Remove(int index, IList items)
             {
-                added(index++, i);
+                for (var i = items.Count - 1; i >= 0; --i)
+                {
+                    removed(index + i, (T)items[i]);
+                }
             }
 
-            collection.CollectionChanged += handler;
-
-            return Disposable.Create(() => collection.CollectionChanged -= handler);
-        }
-
-        /// <summary>
-        /// Invokes an action for each item in a collection and subsequently each item added or
-        /// removed from the collection.
-        /// </summary>
-        /// <typeparam name="T">The type of the collection items.</typeparam>
-        /// <param name="collection">The collection.</param>
-        /// <param name="added">
-        /// An action called initially with all items in the collection and subsequently with a
-        /// list of items added to the collection. The parameters passed are the index of the
-        /// first item added to the collection and the items added.
-        /// </param>
-        /// <param name="removed">
-        /// An action called with all items removed from the collection. The parameters passed 
-        /// are the index of the first item removed from the collection and the items removed.
-        /// </param>
-        /// <param name="reset">
-        /// An action called when the collection is reset.
-        /// </param>
-        /// <returns>A disposable used to terminate the subscription.</returns>
-        public static IDisposable ForEachItem<T>(
-            this IAvaloniaReadOnlyList<T> collection,
-            Action<int, IEnumerable<T>> added,
-            Action<int, IEnumerable<T>> removed,
-            Action reset)
-        {
             NotifyCollectionChangedEventHandler handler = (_, e) =>
             {
                 switch (e.Action)
                 {
                     case NotifyCollectionChangedAction.Add:
-                        added(e.NewStartingIndex, e.NewItems.Cast<T>());
+                        Add(e.NewStartingIndex, e.NewItems);
                         break;
 
+                    case NotifyCollectionChangedAction.Move:
                     case NotifyCollectionChangedAction.Replace:
-                        removed(e.OldStartingIndex, e.OldItems.Cast<T>());
-                        added(e.NewStartingIndex, e.NewItems.Cast<T>());
+                        Remove(e.OldStartingIndex, e.OldItems);
+                        Add(e.NewStartingIndex, e.NewItems);
                         break;
 
                     case NotifyCollectionChangedAction.Remove:
-                        removed(e.OldStartingIndex, e.OldItems.Cast<T>());
+                        Remove(e.OldStartingIndex, e.OldItems);
                         break;
 
                     case NotifyCollectionChangedAction.Reset:
@@ -184,16 +112,31 @@ namespace Avalonia.Collections
                         }
 
                         reset();
+                        Add(0, (IList)collection);
                         break;
                 }
             };
 
-            added(0, collection);
+            Add(0, (IList)collection);
             collection.CollectionChanged += handler;
 
             return Disposable.Create(() => collection.CollectionChanged -= handler);
         }
 
+        public static IAvaloniaReadOnlyList<TDerived> CreateDerivedList<TSource, TDerived>(
+            this IAvaloniaReadOnlyList<TSource> collection,
+            Func<TSource, TDerived> select)
+        {
+            var result = new AvaloniaList<TDerived>();
+
+            collection.ForEachItem(
+                (i, item) => result.Insert(i, select(item)),
+                (i, item) => result.RemoveAt(i),
+                () => result.Clear());
+
+            return result;
+        }
+
         /// <summary>
         /// Listens for property changed events from all items in a collection.
         /// </summary>

+ 9 - 30
src/Avalonia.Base/Data/BindingNotification.cs

@@ -2,6 +2,7 @@
 // Licensed under the MIT license. See licence.md file in the project root for full license information.
 
 using System;
+using Avalonia.Logging;
 
 namespace Avalonia.Data
 {
@@ -44,11 +45,7 @@ namespace Avalonia.Data
         public static readonly BindingNotification UnsetValue =
             new BindingNotification(AvaloniaProperty.UnsetValue);
 
-        // Null cannot be held in WeakReference as it's indistinguishable from an expired value so
-        // use this value in its place.
-        private static readonly object NullValue = new object();
-
-        private WeakReference<object> _value;
+        private object _value;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="BindingNotification"/> class.
@@ -56,7 +53,7 @@ namespace Avalonia.Data
         /// <param name="value">The binding value.</param>
         public BindingNotification(object value)
         {
-            _value = new WeakReference<object>(value ?? NullValue);
+            _value = value;
         }
 
         /// <summary>
@@ -73,6 +70,7 @@ namespace Avalonia.Data
 
             Error = error;
             ErrorType = errorType;
+            _value = AvaloniaProperty.UnsetValue;
         }
 
         /// <summary>
@@ -84,7 +82,7 @@ namespace Avalonia.Data
         public BindingNotification(Exception error, BindingErrorType errorType, object fallbackValue)
             : this(error, errorType)
         {
-            _value = new WeakReference<object>(fallbackValue ?? NullValue);
+            _value = fallbackValue;
         }
 
         /// <summary>
@@ -95,31 +93,12 @@ namespace Avalonia.Data
         /// If this property is read when <see cref="HasValue"/> is false then it will return
         /// <see cref="AvaloniaProperty.UnsetValue"/>.
         /// </remarks>
-        public object Value
-        {
-            get
-            {
-                if (_value != null)
-                {
-                    object result;
-
-                    if (_value.TryGetTarget(out result))
-                    {
-                        return result == NullValue ? null : result;
-                    }
-                }
-
-                // There's the possibility of a race condition in that HasValue can return true,
-                // and then the value is GC'd before Value is read. We should be ok though as
-                // we return UnsetValue which should be a safe alternative.
-                return AvaloniaProperty.UnsetValue;
-            }
-        }
+        public object Value => _value;
 
         /// <summary>
         /// Gets a value indicating whether <see cref="Value"/> should be pushed to the target.
         /// </summary>
-        public bool HasValue => _value != null;
+        public bool HasValue => _value != AvaloniaProperty.UnsetValue;
 
         /// <summary>
         /// Gets the error that occurred on the source, if any.
@@ -248,7 +227,7 @@ namespace Avalonia.Data
         /// </summary>
         public void ClearValue()
         {
-            _value = null;
+            _value = AvaloniaProperty.UnsetValue;
         }
 
         /// <summary>
@@ -256,7 +235,7 @@ namespace Avalonia.Data
         /// </summary>
         public void SetValue(object value)
         {
-            _value = new WeakReference<object>(value ?? NullValue);
+            _value = value;
         }
 
         /// <inheritdoc/>

+ 53 - 0
src/Avalonia.Base/Logging/LoggerExtensions.cs

@@ -0,0 +1,53 @@
+using System;
+using Avalonia.Data;
+
+namespace Avalonia.Logging
+{
+    internal static class LoggerExtensions
+    {
+        public static void LogIfError(
+            this BindingNotification notification,
+            object source,
+            AvaloniaProperty property)
+        {
+            if (notification.ErrorType == BindingErrorType.Error)
+            {
+                if (notification.Error is AggregateException aggregate)
+                {
+                    foreach (var inner in aggregate.InnerExceptions)
+                    {
+                        LogError(source, property, inner);
+                    }
+                }
+                else
+                {
+                    LogError(source, property, notification.Error);
+                }
+            }
+        }
+
+        private static void LogError(object source, AvaloniaProperty property, Exception e)
+        {
+            var level = LogEventLevel.Warning;
+
+            if (e is BindingChainException b &&
+                !string.IsNullOrEmpty(b.Expression) &&
+                string.IsNullOrEmpty(b.ExpressionErrorPoint))
+            {
+                // The error occurred at the root of the binding chain: it's possible that the
+                // DataContext isn't set up yet, so log at Information level instead of Warning
+                // to prevent spewing hundreds of errors.
+                level = LogEventLevel.Information;
+            }
+
+            Logger.Log(
+                level,
+                LogArea.Binding,
+                source,
+                "Error in binding to {Target}.{Property}: {Message}",
+                source,
+                property,
+                e.Message);
+        }
+    }
+}

+ 15 - 0
src/Avalonia.Base/Metadata/AmbientAttribute.cs

@@ -0,0 +1,15 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+
+namespace Avalonia.Metadata
+{
+    /// <summary>
+    /// Defines the ambient class/property 
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property, Inherited = true)]
+    public class AmbientAttribute : Attribute
+    {
+    }
+}

+ 15 - 0
src/Avalonia.Base/Metadata/TemplateContent.cs

@@ -0,0 +1,15 @@
+// Copyright (c) The Avalonia Project. All rights reserved.
+// Licensed under the MIT license. See licence.md file in the project root for full license information.
+
+using System;
+
+namespace Avalonia.Metadata
+{
+    /// <summary>
+    /// Defines the property that contains the object's content in markup.
+    /// </summary>
+    [AttributeUsage(AttributeTargets.Property)]
+    public class TemplateContentAttribute : Attribute
+    {
+    }
+}

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

@@ -98,7 +98,7 @@ namespace Avalonia
 
             if (notification != null)
             {
-                if (notification.HasValue)
+                if (notification.HasValue || notification.ErrorType == BindingErrorType.Error)
                 {
                     Value = notification.Value;
                     _owner.Changed(this);

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

@@ -189,14 +189,7 @@ namespace Avalonia
         /// <param name="error">The binding error.</param>
         public void LevelError(PriorityLevel level, BindingNotification error)
         {
-            Logger.Log(
-                LogEventLevel.Error,
-                LogArea.Binding,
-                Owner,
-                "Error in binding to {Target}.{Property}: {Message}",
-                Owner,
-                Property,
-                error.Error.Message);
+            error.LogIfError(Owner, Property);
         }
 
         /// <summary>

+ 0 - 23
src/Avalonia.Base/Utilities/ExceptionUtilities.cs

@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Avalonia.Utilities
-{
-    internal static class ExceptionUtilities
-    {
-        public static string GetMessage(Exception e)
-        {
-            var aggregate = e as AggregateException;
-
-            if (aggregate != null)
-            {
-                return string.Join(" | ", aggregate.InnerExceptions.Select(x => x.Message));
-            }
-
-            return e.Message;
-        }
-    }
-}

+ 3 - 2
src/Avalonia.Base/Utilities/WeakObservable.cs

@@ -16,12 +16,13 @@ namespace Avalonia.Utilities
         /// Converts a .NET event conforming to the standard .NET event pattern into an observable
         /// sequence, subscribing weakly.
         /// </summary>
+        /// <typeparam name="TTarget">The type of target.</typeparam>
         /// <typeparam name="TEventArgs">The type of the event args.</typeparam>
         /// <param name="target">Object instance that exposes the event to convert.</param>
         /// <param name="eventName">Name of the event to convert.</param>
         /// <returns></returns>
-        public static IObservable<EventPattern<object, TEventArgs>> FromEventPattern<TEventArgs>(
-            object target, 
+        public static IObservable<EventPattern<object, TEventArgs>> FromEventPattern<TTarget, TEventArgs>(
+            TTarget target, 
             string eventName)
             where TEventArgs : EventArgs
         {

+ 12 - 12
src/Avalonia.Base/Utilities/WeakSubscriptionManager.cs

@@ -17,22 +17,23 @@ namespace Avalonia.Utilities
         /// <summary>
         /// Subscribes to an event on an object using a weak subscription.
         /// </summary>
-        /// <typeparam name="T">The type of the event arguments.</typeparam>
+        /// <typeparam name="TTarget">The type of the target.</typeparam>
+        /// <typeparam name="TEventArgs">The type of the event arguments.</typeparam>
         /// <param name="target">The event source.</param>
         /// <param name="eventName">The name of the event.</param>
         /// <param name="subscriber">The subscriber.</param>
-        public static void Subscribe<T>(object target, string eventName, IWeakSubscriber<T> subscriber)
-            where T : EventArgs
+        public static void Subscribe<TTarget, TEventArgs>(TTarget target, string eventName, IWeakSubscriber<TEventArgs> subscriber)
+            where TEventArgs : EventArgs
         {
-            var dic = SubscriptionTypeStorage<T>.Subscribers.GetOrCreateValue(target);
-            Subscription<T> sub;
+            var dic = SubscriptionTypeStorage<TEventArgs>.Subscribers.GetOrCreateValue(target);
+            Subscription<TEventArgs> sub;
 
             if (!dic.TryGetValue(eventName, out sub))
             {
-                dic[eventName] = sub = new Subscription<T>(dic, target, eventName);
+                dic[eventName] = sub = new Subscription<TEventArgs>(dic, typeof(TTarget), target, eventName);
             }
 
-            sub.Add(new WeakReference<IWeakSubscriber<T>>(subscriber));
+            sub.Add(new WeakReference<IWeakSubscriber<TEventArgs>>(subscriber));
         }
 
         /// <summary>
@@ -84,19 +85,18 @@ namespace Avalonia.Utilities
             private WeakReference<IWeakSubscriber<T>>[] _data = new WeakReference<IWeakSubscriber<T>>[16];
             private int _count = 0;
 
-            public Subscription(SubscriptionDic<T> sdic, object target, string eventName)
+            public Subscription(SubscriptionDic<T> sdic, Type targetType, object target, string eventName)
             {
                 _sdic = sdic;
                 _target = target;
                 _eventName = eventName;
-                var t = target.GetType();
                 Dictionary<string, EventInfo> evDic;
-                if (!Accessors.TryGetValue(t, out evDic))
-                    Accessors[t] = evDic = new Dictionary<string, EventInfo>();
+                if (!Accessors.TryGetValue(targetType, out evDic))
+                    Accessors[targetType] = evDic = new Dictionary<string, EventInfo>();
 
                 if (!evDic.TryGetValue(eventName, out _info))
                 {
-                    var ev = t.GetRuntimeEvents().FirstOrDefault(x => x.Name == eventName);
+                    var ev = targetType.GetRuntimeEvents().FirstOrDefault(x => x.Name == eventName);
 
                     if (ev == null)
                     {

+ 57 - 9
src/Avalonia.Controls/Application.cs

@@ -29,7 +29,7 @@ namespace Avalonia
     /// method.
     /// - Tracks the lifetime of the application.
     /// </remarks>
-    public class Application : IGlobalDataTemplates, IGlobalStyles, IStyleRoot, IApplicationLifecycle
+    public class Application : IApplicationLifecycle, IGlobalDataTemplates, IGlobalStyles, IStyleRoot, IResourceNode
     {
         /// <summary>
         /// The application-global data templates.
@@ -39,6 +39,8 @@ namespace Avalonia
         private readonly Lazy<IClipboard> _clipboard =
             new Lazy<IClipboard>(() => (IClipboard)AvaloniaLocator.Current.GetService(typeof(IClipboard)));
         private readonly Styler _styler = new Styler();
+        private Styles _styles;
+        private IResourceDictionary _resources;
 
         /// <summary>
         /// Initializes a new instance of the <see cref="Application"/> class.
@@ -48,6 +50,9 @@ namespace Avalonia
             OnExit += OnExiting;
         }
 
+        /// <inheritdoc/>
+        public event EventHandler<ResourcesChangedEventArgs> ResourcesChanged;
+
         /// <summary>
         /// Gets the current instance of the <see cref="Application"/> class.
         /// </summary>
@@ -65,11 +70,7 @@ namespace Avalonia
         /// <value>
         /// The application's global data templates.
         /// </value>
-        public DataTemplates DataTemplates
-        {
-            get { return _dataTemplates ?? (_dataTemplates = new DataTemplates()); }
-            set { _dataTemplates = value; }
-        }
+        public DataTemplates DataTemplates => _dataTemplates ?? (_dataTemplates = new DataTemplates());
 
         /// <summary>
         /// Gets the application's focus manager.
@@ -100,6 +101,34 @@ namespace Avalonia
         /// </summary>
         public IClipboard Clipboard => _clipboard.Value;
 
+        /// <summary>
+        /// Gets the application's global resource dictionary.
+        /// </summary>
+        public IResourceDictionary Resources
+        {
+            get => _resources ?? (Resources = new ResourceDictionary());
+            set
+            {
+                Contract.Requires<ArgumentNullException>(value != null);
+
+                var hadResources = false;
+
+                if (_resources != null)
+                {
+                    hadResources = _resources.Count > 0;
+                    _resources.ResourcesChanged -= ResourcesChanged;
+                }
+
+                _resources = value;
+                _resources.ResourcesChanged += ResourcesChanged;
+
+                if (hadResources || _resources.Count > 0)
+                {
+                    ResourcesChanged?.Invoke(this, new ResourcesChangedEventArgs());
+                }
+            }
+        }
+
         /// <summary>
         /// Gets the application's global styles.
         /// </summary>
@@ -109,13 +138,25 @@ namespace Avalonia
         /// <remarks>
         /// Global styles apply to all windows in the application.
         /// </remarks>
-        public Styles Styles { get; } = new Styles();
+        public Styles Styles => _styles ?? (_styles = new Styles());
+
+        /// <inheritdoc/>
+        bool IDataTemplateHost.IsDataTemplatesInitialized => _dataTemplates != null;
 
         /// <summary>
         /// Gets the styling parent of the application, which is null.
         /// </summary>
         IStyleHost IStyleHost.StylingParent => null;
 
+        /// <inheritdoc/>
+        bool IStyleHost.IsStylesInitialized => _styles != null;
+
+        /// <inheritdoc/>
+        bool IResourceProvider.HasResources => _resources?.Count > 0;
+
+        /// <inheritdoc/>
+        IResourceNode IResourceNode.ResourceParent => null;
+
         /// <summary>
         /// Initializes the application by loading XAML etc.
         /// </summary>
@@ -142,13 +183,20 @@ namespace Avalonia
         {
             OnExit?.Invoke(this, EventArgs.Empty);
         }
-        
+
+        /// <inheritdoc/>
+        bool IResourceProvider.TryGetResource(string key, out object value)
+        {
+            value = null;
+            return (_resources?.TryGetResource(key, out value) ?? false) ||
+                   Styles.TryGetResource(key, out value);
+        }
+
         /// <summary>
         /// Sent when the application is exiting.
         /// </summary>
         public event EventHandler OnExit;
 
-
         /// <summary>
         /// Called when the application is exiting.
         /// </summary>

+ 1 - 1
src/Avalonia.Controls/Avalonia.Controls.csproj

@@ -1,6 +1,6 @@
 <Project Sdk="Microsoft.NET.Sdk">
   <PropertyGroup>
-    <TargetFramework>netstandard1.1</TargetFramework>
+    <TargetFramework>netstandard2.0</TargetFramework>
     <GenerateAssemblyInfo>false</GenerateAssemblyInfo>
   </PropertyGroup>
   <PropertyGroup Condition=" '$(Configuration)' == 'Debug' ">

+ 42 - 16
src/Avalonia.Controls/Button.cs

@@ -4,6 +4,7 @@
 using System;
 using System.Linq;
 using System.Windows.Input;
+using Avalonia.Data;
 using Avalonia.Input;
 using Avalonia.Interactivity;
 using Avalonia.Rendering;
@@ -41,8 +42,9 @@ namespace Avalonia.Controls
         /// <summary>
         /// Defines the <see cref="Command"/> property.
         /// </summary>
-        public static readonly StyledProperty<ICommand> CommandProperty =
-            AvaloniaProperty.Register<Button, ICommand>(nameof(Command));
+        public static readonly DirectProperty<Button, ICommand> CommandProperty =
+            AvaloniaProperty.RegisterDirect<Button, ICommand>(nameof(Command),
+                button => button.Command, (button, command) => button.Command = command, enableDataValidation: true);
 
         /// <summary>
         /// Defines the <see cref="HotKey"/> property.
@@ -68,6 +70,8 @@ namespace Avalonia.Controls
         public static readonly RoutedEvent<RoutedEventArgs> ClickEvent =
             RoutedEvent.Register<Button, RoutedEventArgs>("Click", RoutingStrategies.Bubble);
 
+        private ICommand _command;
+
         /// <summary>
         /// Initializes static members of the <see cref="Button"/> class.
         /// </summary>
@@ -102,8 +106,8 @@ namespace Avalonia.Controls
         /// </summary>
         public ICommand Command
         {
-            get { return GetValue(CommandProperty); }
-            set { SetValue(CommandProperty, value); }
+            get { return _command; }
+            set { SetAndRaise(CommandProperty, ref _command, value); }
         }
 
         /// <summary>
@@ -207,7 +211,11 @@ namespace Avalonia.Controls
         /// <param name="e">The event args.</param>
         protected virtual void OnClick(RoutedEventArgs e)
         {
-            Command?.Execute(CommandParameter);
+            if (Command != null)
+            {
+                Command.Execute(CommandParameter);
+                e.Handled = true;
+            }
         }
 
         /// <inheritdoc/>
@@ -215,13 +223,16 @@ namespace Avalonia.Controls
         {
             base.OnPointerPressed(e);
 
-            PseudoClasses.Add(":pressed");
-            e.Device.Capture(this);
-            e.Handled = true;
-
-            if (ClickMode == ClickMode.Press)
+            if (e.MouseButton == MouseButton.Left)
             {
-                RaiseClickEvent();
+                PseudoClasses.Add(":pressed");
+                e.Device.Capture(this);
+                e.Handled = true;
+
+                if (ClickMode == ClickMode.Press)
+                {
+                    RaiseClickEvent();
+                }
             }
         }
 
@@ -230,13 +241,28 @@ namespace Avalonia.Controls
         {
             base.OnPointerReleased(e);
 
-            e.Device.Capture(null);
-            PseudoClasses.Remove(":pressed");
-            e.Handled = true;
+            if (e.MouseButton == MouseButton.Left)
+            {
+                e.Device.Capture(null);
+                PseudoClasses.Remove(":pressed");
+                e.Handled = true;
+
+                if (ClickMode == ClickMode.Release && new Rect(Bounds.Size).Contains(e.GetPosition(this)))
+                {
+                    RaiseClickEvent();
+                }
+            }
+        }
 
-            if (ClickMode == ClickMode.Release && Classes.Contains(":pointerover"))
+        protected override void UpdateDataValidation(AvaloniaProperty property, BindingNotification status)
+        {
+            base.UpdateDataValidation(property, status);
+            if(property == CommandProperty)
             {
-                RaiseClickEvent();
+                if(status?.ErrorType == BindingErrorType.Error)
+                {
+                    IsEnabled = false;
+                }
             }
         }
 

+ 14 - 0
src/Avalonia.Controls/Classes.cs

@@ -86,6 +86,20 @@ namespace Avalonia.Controls
             base.AddRange(c);
         }
 
+        /// <summary>
+        /// Remvoes all non-pseudoclasses from the collection.
+        /// </summary>
+        public override void Clear()
+        {
+            for (var i = Count - 1; i >= 0; --i)
+            {
+                if (!this[i].StartsWith(":"))
+                {
+                    RemoveAt(i);
+                }
+            }
+        }
+
         /// <summary>
         /// Inserts a style class into the collection.
         /// </summary>

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

@@ -19,7 +19,7 @@ namespace Avalonia.Controls
         {
             ContextMenuProperty.Changed.Subscribe(ContextMenuChanged);
 
-            MenuItem.ClickEvent.AddClassHandler<ContextMenu>(x => x.OnContextMenuClick);            
+            MenuItem.ClickEvent.AddClassHandler<ContextMenu>(x => x.OnContextMenuClick, handledEventsToo: true);            
         }
 
         /// <summary>

+ 148 - 52
src/Avalonia.Controls/Control.cs

@@ -97,6 +97,7 @@ namespace Avalonia.Controls
         private bool _isAttachedToLogicalTree;
         private IAvaloniaList<ILogical> _logicalChildren;
         private INameScope _nameScope;
+        private IResourceDictionary _resources;
         private Styles _styles;
         private bool _styled;
         private Subject<IStyleable> _styleDetach = new Subject<IStyleable>();
@@ -118,6 +119,7 @@ namespace Avalonia.Controls
         public Control()
         {
             _nameScope = this as INameScope;
+            _isAttachedToLogicalTree = this is IStyleRoot;
         }
 
         /// <summary>
@@ -152,6 +154,11 @@ namespace Avalonia.Controls
         /// </remarks>
         public event EventHandler Initialized;
 
+        /// <summary>
+        /// Occurs when a resource in this control or a parent control has changed.
+        /// </summary>
+        public event EventHandler<ResourcesChangedEventArgs> ResourcesChanged;
+
         /// <summary>
         /// Gets or sets the name of the control.
         /// </summary>
@@ -242,11 +249,7 @@ namespace Avalonia.Controls
         /// Each control may define data templates which are applied to the control itself and its
         /// children.
         /// </remarks>
-        public DataTemplates DataTemplates
-        {
-            get { return _dataTemplates ?? (_dataTemplates = new DataTemplates()); }
-            set { _dataTemplates = value; }
-        }
+        public DataTemplates DataTemplates => _dataTemplates ?? (_dataTemplates = new DataTemplates());
 
         /// <summary>
         /// Gets a value that indicates whether the element has finished initialization.
@@ -258,7 +261,7 @@ namespace Avalonia.Controls
         public bool IsInitialized { get; private set; }
 
         /// <summary>
-        /// Gets or sets the styles for the control.
+        /// Gets the styles for the control.
         /// </summary>
         /// <remarks>
         /// Styles for the entire application are added to the Application.Styles collection, but
@@ -267,8 +270,29 @@ namespace Avalonia.Controls
         /// </remarks>
         public Styles Styles
         {
-            get { return _styles ?? (_styles = new Styles()); }
-            set { _styles = value; }
+            get { return _styles ?? (Styles = new Styles()); }
+            set
+            {
+                Contract.Requires<ArgumentNullException>(value != null);
+
+                if (_styles != value)
+                {
+                    if (_styles != null)
+                    {
+                        (_styles as ISetStyleParent)?.SetParent(null);
+                        _styles.ResourcesChanged -= ThisResourcesChanged;
+                    }
+
+                    _styles = value;
+
+                    if (value is ISetStyleParent setParent && setParent.ResourceParent == null)
+                    {
+                        setParent.SetParent(this);
+                    } 
+
+                    _styles.ResourcesChanged += ThisResourcesChanged;
+                }
+            }
         }
 
         /// <summary>
@@ -285,6 +309,34 @@ namespace Avalonia.Controls
             set { SetValue(ContextMenuProperty, value); }
         }
 
+        /// <summary>
+        /// Gets or sets the control's resource dictionary.
+        /// </summary>
+        public IResourceDictionary Resources
+        {
+            get => _resources ?? (Resources = new ResourceDictionary());
+            set
+            {
+                Contract.Requires<ArgumentNullException>(value != null);
+
+                var hadResources = false;
+
+                if (_resources != null)
+                {
+                    hadResources = _resources.Count > 0;
+                    _resources.ResourcesChanged -= ThisResourcesChanged;
+                }
+
+                _resources = value;
+                _resources.ResourcesChanged += ThisResourcesChanged;
+
+                if (hadResources || _resources.Count > 0)
+                {
+                    ((ILogical)this).NotifyResourcesChanged(new ResourcesChangedEventArgs());
+                }
+            }
+        }
+
         /// <summary>
         /// Gets or sets a user-defined object attached to the control.
         /// </summary>
@@ -303,6 +355,35 @@ namespace Avalonia.Controls
             internal set { SetValue(TemplatedParentProperty, value); }
         }
 
+        /// <summary>
+        /// Gets the control's logical children.
+        /// </summary>
+        protected IAvaloniaList<ILogical> LogicalChildren
+        {
+            get
+            {
+                if (_logicalChildren == null)
+                {
+                    var list = new AvaloniaList<ILogical>();
+                    list.ResetBehavior = ResetBehavior.Remove;
+                    list.Validate = ValidateLogicalChild;
+                    list.CollectionChanged += LogicalChildrenCollectionChanged;
+                    _logicalChildren = list;
+                }
+
+                return _logicalChildren;
+            }
+        }
+
+        /// <inheritdoc/>
+        bool IDataTemplateHost.IsDataTemplatesInitialized => _dataTemplates != null;
+
+        /// <summary>
+        /// Gets the <see cref="Classes"/> collection in a form that allows adding and removing
+        /// pseudoclasses.
+        /// </summary>
+        protected IPseudoClasses PseudoClasses => Classes;
+
         /// <summary>
         /// Gets a value indicating whether the element is attached to a rooted logical tree.
         /// </summary>
@@ -318,6 +399,12 @@ namespace Avalonia.Controls
         /// </summary>
         IAvaloniaReadOnlyList<ILogical> ILogical.LogicalChildren => LogicalChildren;
 
+        /// <inheritdoc/>
+        bool IResourceProvider.HasResources => _resources?.Count > 0 || Styles.HasResources;
+
+        /// <inheritdoc/>
+        IResourceNode IResourceNode.ResourceParent => ((IStyleHost)this).StylingParent as IResourceNode;
+
         /// <inheritdoc/>
         IAvaloniaReadOnlyList<string> IStyleable.Classes => Classes;
 
@@ -335,6 +422,9 @@ namespace Avalonia.Controls
         /// <inheritdoc/>
         IObservable<IStyleable> IStyleable.StyleDetach => _styleDetach;
 
+        /// <inheritdoc/>
+        bool IStyleHost.IsStylesInitialized => _styles != null;
+
         /// <inheritdoc/>
         IStyleHost IStyleHost.StylingParent => (IStyleHost)InheritanceParent;
 
@@ -354,52 +444,61 @@ namespace Avalonia.Controls
 
             if (--_initCount == 0 && _isAttachedToLogicalTree)
             {
-                if (!_styled)
-                {
-                    RegisterWithNameScope();
-                    ApplyStyling();
-                    _styled = true;
-                }
+                InitializeStylesIfNeeded();
 
-                if (!IsInitialized)
-                {
-                    IsInitialized = true;
-                    Initialized?.Invoke(this, EventArgs.Empty);
-                }
+                InitializeIfNeeded();
+            }
+        }
+
+        private void InitializeStylesIfNeeded(bool force = false)
+        {
+            if (_initCount == 0 && (!_styled || force))
+            {
+                RegisterWithNameScope();
+                ApplyStyling();
+                _styled = true;
+            }
+        }
+
+        private void InitializeIfNeeded()
+        {
+            if (_initCount == 0 && !IsInitialized)
+            {
+                IsInitialized = true;
+                Initialized?.Invoke(this, EventArgs.Empty);
             }
         }
 
+        /// <inheritdoc/>
+        void ILogical.NotifyAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
+        {
+            this.OnAttachedToLogicalTreeCore(e);
+        }
+
         /// <inheritdoc/>
         void ILogical.NotifyDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
         {
             this.OnDetachedFromLogicalTreeCore(e);
         }
 
-        /// <summary>
-        /// Gets the control's logical children.
-        /// </summary>
-        protected IAvaloniaList<ILogical> LogicalChildren
+        /// <inheritdoc/>
+        void ILogical.NotifyResourcesChanged(ResourcesChangedEventArgs e)
         {
-            get
-            {
-                if (_logicalChildren == null)
-                {
-                    var list = new AvaloniaList<ILogical>();
-                    list.ResetBehavior = ResetBehavior.Remove;
-                    list.Validate = ValidateLogicalChild;
-                    list.CollectionChanged += LogicalChildrenCollectionChanged;
-                    _logicalChildren = list;
-                }
+            ResourcesChanged?.Invoke(this, new ResourcesChangedEventArgs());
 
-                return _logicalChildren;
+            foreach (var child in LogicalChildren)
+            {
+                child.NotifyResourcesChanged(e);
             }
         }
 
-        /// <summary>
-        /// Gets the <see cref="Classes"/> collection in a form that allows adding and removing
-        /// pseudoclasses.
-        /// </summary>
-        protected IPseudoClasses PseudoClasses => Classes;
+        /// <inheritdoc/>
+        bool IResourceProvider.TryGetResource(string key, out object value)
+        {
+            value = null;
+            return (_resources?.TryGetResource(key, out value) ?? false) ||
+                   (_styles?.TryGetResource(key, out value) ?? false);
+        }
 
         /// <summary>
         /// Sets the control's logical parent.
@@ -418,7 +517,7 @@ namespace Avalonia.Controls
 
                 if (_isAttachedToLogicalTree)
                 {
-                    var oldRoot = FindStyleRoot(old);
+                    var oldRoot = FindStyleRoot(old) ?? this as IStyleRoot;
 
                     if (oldRoot == null)
                     {
@@ -435,8 +534,9 @@ namespace Avalonia.Controls
                 }
 
                 _parent = (IControl)parent;
+                ((ILogical)this).NotifyResourcesChanged(new ResourcesChangedEventArgs());
 
-                if (_parent is IStyleRoot || _parent?.IsAttachedToLogicalTree == true)
+                if (_parent is IStyleRoot || _parent?.IsAttachedToLogicalTree == true || this is IStyleRoot)
                 {
                     var newRoot = FindStyleRoot(this);
 
@@ -573,11 +673,7 @@ namespace Avalonia.Controls
         {
             base.OnAttachedToVisualTreeCore(e);
 
-            if (!IsInitialized)
-            {
-                IsInitialized = true;
-                Initialized?.Invoke(this, EventArgs.Empty);
-            }
+            InitializeIfNeeded();
         }
 
         /// <inheritdoc/>
@@ -745,12 +841,7 @@ namespace Avalonia.Controls
             {
                 _isAttachedToLogicalTree = true;
 
-                if (_initCount == 0)
-                {
-                    RegisterWithNameScope();
-                    ApplyStyling();
-                    _styled = true;
-                }
+                InitializeStylesIfNeeded(true);
 
                 OnAttachedToLogicalTree(e);
             }
@@ -835,5 +926,10 @@ namespace Avalonia.Controls
                 }
             }
         }
+
+        private void ThisResourcesChanged(object sender, ResourcesChangedEventArgs e)
+        {
+            ((ILogical)this).NotifyResourcesChanged(e);
+        }
     }
 }

+ 59 - 0
src/Avalonia.Controls/DrawingPresenter.cs

@@ -0,0 +1,59 @@
+using Avalonia.Controls.Shapes;
+using Avalonia.Media;
+using Avalonia.Metadata;
+
+namespace Avalonia.Controls
+{
+    public class DrawingPresenter : Control
+    {
+        static DrawingPresenter()
+        {
+            AffectsMeasure(DrawingProperty);
+            AffectsRender(DrawingProperty);
+        }
+
+        public static readonly StyledProperty<Drawing> DrawingProperty =
+            AvaloniaProperty.Register<DrawingPresenter, Drawing>(nameof(Drawing));
+
+        public static readonly StyledProperty<Stretch> StretchProperty =
+            AvaloniaProperty.Register<DrawingPresenter, Stretch>(nameof(Stretch), Stretch.Uniform);
+
+        [Content]
+        public Drawing Drawing
+        {
+            get => GetValue(DrawingProperty);
+            set => SetValue(DrawingProperty, value);
+        }
+
+        public Stretch Stretch
+        {
+            get => GetValue(StretchProperty);
+            set => SetValue(StretchProperty, value);
+        }
+
+        private Matrix _transform = Matrix.Identity;
+
+        protected override Size MeasureOverride(Size availableSize)
+        {
+            if (Drawing == null) return new Size();
+
+            var (size, transform) = Shape.CalculateSizeAndTransform(availableSize, Drawing.GetBounds(), Stretch);
+
+            _transform = transform;
+
+            return size;
+        }
+
+        public override void Render(DrawingContext context)
+        {
+            if (Drawing != null)
+            {
+                using (context.PushPreTransform(_transform))
+                using (context.PushClip(Bounds))
+                {
+                    Drawing.Draw(context);
+                }
+            }
+        }
+    }
+}

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

@@ -120,7 +120,7 @@ namespace Avalonia.Controls
         /// <inheritdoc/>
         protected override void OnPointerPressed(PointerPressedEventArgs e)
         {
-            if (!IsDropDownOpen && ((IVisual)e.Source).GetVisualRoot() != typeof(PopupRoot))
+            if (!IsDropDownOpen && ((IVisual)e.Source).GetVisualRoot() is PopupRoot)
             {
                 IsDropDownOpen = true;
                 e.Handled = true;

+ 6 - 4
src/Avalonia.Controls/Embedding/EmbeddableControlRoot.cs

@@ -22,6 +22,8 @@ namespace Avalonia.Controls.Embedding
         [CanBeNull]
         public new IEmbeddableWindowImpl PlatformImpl => (IEmbeddableWindowImpl) base.PlatformImpl;
 
+        protected bool EnforceClientSize { get; set; } = true;
+
         public void Prepare()
         {
             EnsureInitialized();
@@ -38,12 +40,12 @@ namespace Avalonia.Controls.Embedding
                 init.EndInit();
             }
         }
-
+        
         protected override Size MeasureOverride(Size availableSize)
         {
-            var cs = PlatformImpl?.ClientSize ?? default(Size);
-            base.MeasureOverride(cs);
-            return cs;
+            if (EnforceClientSize)
+                availableSize = PlatformImpl?.ClientSize ?? default(Size);
+            return base.MeasureOverride(availableSize);
         }
 
         private readonly NameScope _nameScope = new NameScope();

+ 9 - 6
src/Avalonia.Controls/IControl.cs

@@ -14,7 +14,15 @@ namespace Avalonia.Controls
     /// <summary>
     /// Interface for Avalonia controls.
     /// </summary>
-    public interface IControl : IVisual, ILogical, ILayoutable, IInputElement, INamed, IStyleable, IStyleHost
+    public interface IControl : IVisual,
+        IDataTemplateHost,
+        ILogical,
+        ILayoutable,
+        IInputElement,
+        INamed,
+        IResourceNode,
+        IStyleable,
+        IStyleHost
     {
         /// <summary>
         /// Occurs when the control has finished initialization.
@@ -31,11 +39,6 @@ namespace Avalonia.Controls
         /// </summary>
         object DataContext { get; set; }
 
-        /// <summary>
-        /// Gets the data templates for the control.
-        /// </summary>
-        DataTemplates DataTemplates { get; }
-
         /// <summary>
         /// Gets a value that indicates whether the element has finished initialization.
         /// </summary>

+ 1 - 5
src/Avalonia.Controls/IGlobalDataTemplates.cs

@@ -8,11 +8,7 @@ namespace Avalonia.Controls
     /// <summary>
     /// Defines the application-global data templates.
     /// </summary>
-    public interface IGlobalDataTemplates
+    public interface IGlobalDataTemplates : IDataTemplateHost
     {
-        /// <summary>
-        /// Gets the application-global data templates.
-        /// </summary>
-        DataTemplates DataTemplates { get; }
     }
 }

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

@@ -47,7 +47,7 @@ namespace Avalonia.Controls
         static Menu()
         {
             ItemsPanelProperty.OverrideDefaultValue(typeof(Menu), DefaultPanel);
-            MenuItem.ClickEvent.AddClassHandler<Menu>(x => x.OnMenuClick);
+            MenuItem.ClickEvent.AddClassHandler<Menu>(x => x.OnMenuClick, handledEventsToo: true);
             MenuItem.SubmenuOpenedEvent.AddClassHandler<Menu>(x => x.OnSubmenuOpened);
         }
 

+ 11 - 2
src/Avalonia.Controls/MenuItem.cs

@@ -24,7 +24,7 @@ namespace Avalonia.Controls
         /// Defines the <see cref="Command"/> property.
         /// </summary>
         public static readonly StyledProperty<ICommand> CommandProperty =
-            Button.CommandProperty.AddOwner<MenuItem>();
+            AvaloniaProperty.Register<MenuItem, ICommand>(nameof(Command));
 
         /// <summary>
         /// Defines the <see cref="HotKey"/> property.
@@ -102,6 +102,11 @@ namespace Avalonia.Controls
             AccessKeyHandler.AccessKeyPressedEvent.AddClassHandler<MenuItem>(x => x.AccessKeyPressed);
         }
 
+        public MenuItem()
+        {
+
+        }
+
         /// <summary>
         /// Occurs when a <see cref="MenuItem"/> without a submenu is clicked.
         /// </summary>
@@ -192,7 +197,11 @@ namespace Avalonia.Controls
         /// <param name="e">The click event args.</param>
         protected virtual void OnClick(RoutedEventArgs e)
         {
-            Command?.Execute(CommandParameter);
+            if (Command != null)
+            {
+                Command.Execute(CommandParameter);
+                e.Handled = true;
+            }
         }
 
         /// <summary>

+ 6 - 3
src/Avalonia.Controls/Panel.cs

@@ -64,9 +64,12 @@ namespace Avalonia.Controls
             {
                 Contract.Requires<ArgumentNullException>(value != null);
 
-                VisualChildren.Clear();
-                _children.Clear();
-                _children.AddRange(value);
+                if (_children != value)
+                {
+                    VisualChildren.Clear();
+                    _children.Clear();
+                    _children.AddRange(value);
+                }
             }
         }
 

Неке датотеке нису приказане због велике количине промена