Browse Source

Merge branch 'master' into extract-layout-manager

pull/1014/head
Jeremy Koritzinsky 8 years ago
committed by GitHub
parent
commit
fd03d8c6b8
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 17
      .github/PULL_REQUEST_TEMPLATE.md
  2. 11
      .gitignore
  3. 16
      .gitmodules
  4. 5
      .ncrunch/Avalonia.Designer.HostApp.v3.ncrunchproject
  5. 5
      .ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject
  6. 4
      .ncrunch/Avalonia.DotNetCoreRuntime.v3.ncrunchproject
  7. 4
      .ncrunch/Avalonia.Gtk3.v3.ncrunchproject
  8. 5
      .ncrunch/Avalonia.LinuxFramebuffer.v3.ncrunchproject
  9. 9
      .ncrunch/Avalonia.Markup.UnitTests.netcoreapp1.1.v3.ncrunchproject
  10. 5
      .ncrunch/Avalonia.Skia.RenderTests.v3.ncrunchproject
  11. 5
      .ncrunch/Avalonia.Visuals.UnitTests.net461.v3.ncrunchproject
  12. 5
      .ncrunch/Avalonia.Win32.Interop.v3.ncrunchproject
  13. 4
      .ncrunch/Avalonia.Win32.NetStandard.v3.ncrunchproject
  14. 5
      .ncrunch/ControlCatalog.NetCore.v3.ncrunchproject
  15. 5
      .ncrunch/RemoteTest.v3.ncrunchproject
  16. 8
      .travis.yml
  17. 1510
      Avalonia.sln
  18. 1
      Avalonia.sln.DotSettings
  19. 22
      appveyor.yml
  20. 339
      build.cake
  21. 2
      build.ps1
  22. 5
      build/Base.props
  23. 8
      build/Binding.props
  24. 11
      build/EmbedXaml.props
  25. 2
      build/JetBrains.dotMemoryUnit.props
  26. 2
      build/Magick.NET-Q16-AnyCPU.props
  27. 5
      build/Markup.props
  28. 5
      build/MonoMac.props
  29. 2
      build/Moq.props
  30. 2
      build/NetCore.props
  31. 6
      build/NetFX.props
  32. 5
      build/ReactiveUI.props
  33. 12
      build/Rx.props
  34. 13
      build/SampleApp.props
  35. 5
      build/Serilog.Sinks.Trace.props
  36. 4
      build/Serilog.props
  37. 14
      build/SharedVersion.props
  38. 9
      build/SharpDX.props
  39. 2
      build/SkiaSharp.props
  40. 5
      build/SourceLink.props
  41. 5
      build/Splat.props
  42. 5
      build/System.Drawing.Common.props
  43. 20
      build/UnitTests.NetCore.targets
  44. 19
      build/XUnit.props
  45. 15
      cake.config
  46. 3
      docs/.gitignore
  47. 21
      docs/README.md
  48. 3
      docs/build.cmd
  49. 55
      docs/docfx.json
  50. 89
      docs/guidelines/build.md
  51. 60
      docs/guidelines/contributing.md
  52. 4
      docs/guidelines/toc.yml
  53. BIN
      docs/images/avalonia-video.png
  54. BIN
      docs/images/cross-platform.png
  55. BIN
      docs/images/hello-world-xaml.png
  56. BIN
      docs/images/inspection-support.png
  57. BIN
      docs/images/screen.png
  58. 37
      docs/index.md
  59. 225
      docs/intro.md
  60. 2
      docs/serve.cmd
  61. 101
      docs/spec/architecture.md
  62. 156
      docs/spec/binding-from-code.md
  63. 99
      docs/spec/binding-from-xaml.md
  64. 199
      docs/spec/defining-properties.md
  65. 54
      docs/spec/logging.md
  66. 111
      docs/spec/styles.md
  67. 14
      docs/spec/toc.yml
  68. 102
      docs/spec/working-with-properties.md
  69. 13
      docs/template/partials/footer.tmpl.partial
  70. 10
      docs/toc.yml
  71. 172
      docs/tutorial/from-wpf.md
  72. 10
      docs/tutorial/gettingstarted.md
  73. BIN
      docs/tutorial/images/add-dialogs.png
  74. 86
      docs/tutorial/nuget.md
  75. 6
      docs/tutorial/toc.yml
  76. 338
      packages.cake
  77. 42
      parameters.cake
  78. 92
      readme.md
  79. 16
      samples/BindingTest/App.config
  80. 14
      samples/BindingTest/App.xaml.cs
  81. 186
      samples/BindingTest/BindingTest.csproj
  82. 20
      samples/BindingTest/MainWindow.xaml
  83. 36
      samples/BindingTest/Properties/AssemblyInfo.cs
  84. 22
      samples/BindingTest/ViewModels/MainWindowViewModel.cs
  85. 20
      samples/BindingTest/ViewModels/NestedCommandViewModel.cs
  86. 11
      samples/ControlCatalog.Android/ControlCatalog.Android.csproj
  87. 9
      samples/ControlCatalog.Android/Resources/Resource.Designer.cs
  88. 16
      samples/ControlCatalog.Desktop/App.config
  89. 153
      samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj
  90. 22
      samples/ControlCatalog.Desktop/Program.cs
  91. 36
      samples/ControlCatalog.Desktop/Properties/AssemblyInfo.cs
  92. 3
      samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj
  93. 36
      samples/ControlCatalog.NetCore/Program.cs
  94. 14
      samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj
  95. BIN
      samples/ControlCatalog/Assets/Fonts/SourceSansPro-Bold.ttf
  96. BIN
      samples/ControlCatalog/Assets/Fonts/SourceSansPro-BoldItalic.ttf
  97. BIN
      samples/ControlCatalog/Assets/Fonts/SourceSansPro-Italic.ttf
  98. BIN
      samples/ControlCatalog/Assets/Fonts/SourceSansPro-Regular.ttf
  99. BIN
      samples/ControlCatalog/Assets/test_icon.ico
  100. 161
      samples/ControlCatalog/ControlCatalog.csproj

17
.github/PULL_REQUEST_TEMPLATE.md

@ -0,0 +1,17 @@
This template is not intended to be prescriptive, but to help us review pull requests it would be useful if you included as much of the following information as possible:
- What does the pull request do?
- What is the current behavior?
- What is the updated/expected behavior with this PR?
- How was the solution implemented (if it's not obvious)?
Checklist:
- [ ] Added unit tests (if possible)?
- [ ] Added XML documentation to any related classes?
- [ ] Consider submitting a PR to https://github.com/AvaloniaUI/Avaloniaui.net with user documentation
If the pull request fixes issue(s) list them like this:
Fixes #123
Fixes #456

11
.gitignore

@ -108,7 +108,7 @@ AppPackages/
# NCrunch
_NCrunch_*/
*.ncrunchsolution.user
nCrunchTemp_*/
nCrunchTemp_*
# Others
sql/
@ -159,6 +159,12 @@ $RECYCLE.BIN/
*.userprefs
*.nugetreferenceswitcher
#################
## Rider
#################
.idea
#################
## Cake
#################
@ -169,3 +175,6 @@ artifacts/
nuget
Avalonia.XBuild.sln
project.lock.json
.idea/*
**/obj-Skia/*
**/obj-Direct2D1/*

16
.gitmodules

@ -1,13 +1,3 @@
[submodule "src/Avalonia.ReactiveUI/src"]
path = src/Avalonia.ReactiveUI/src
url = https://github.com/reactiveui/ReactiveUI.git
[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

5
.ncrunch/Avalonia.Designer.HostApp.v3.ncrunchproject

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

5
.ncrunch/Avalonia.Direct2D1.RenderTests.v3.ncrunchproject

@ -1,6 +1,9 @@
<ProjectConfiguration>
<Settings>
<DefaultTestTimeout>1000</DefaultTestTimeout>
<AdditionalFilesToIncludeForProject>
<Value>..\TestFiles\Direct2D1\**.*</Value>
</AdditionalFilesToIncludeForProject>
<DefaultTestTimeout>3000</DefaultTestTimeout>
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
</Settings>
</ProjectConfiguration>

4
.ncrunch/Avalonia.DotNetCoreRuntime.v3.ncrunchproject

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

4
.ncrunch/Avalonia.Gtk3.v3.ncrunchproject

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

5
.ncrunch/Avalonia.LinuxFramebuffer.v3.ncrunchproject

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

9
.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>

5
.ncrunch/Avalonia.Skia.RenderTests.v3.ncrunchproject

@ -1,6 +1,9 @@
<ProjectConfiguration>
<Settings>
<DefaultTestTimeout>1000</DefaultTestTimeout>
<AdditionalFilesToIncludeForProject>
<Value>..\TestFiles\Skia\**.*</Value>
</AdditionalFilesToIncludeForProject>
<DefaultTestTimeout>3000</DefaultTestTimeout>
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully>
</Settings>
</ProjectConfiguration>

5
.ncrunch/Avalonia.Visuals.UnitTests.net461.v3.ncrunchproject

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

5
.ncrunch/Avalonia.Win32.Interop.v3.ncrunchproject

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

4
.ncrunch/Avalonia.Win32.NetStandard.v3.ncrunchproject

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

5
.ncrunch/ControlCatalog.NetCore.v3.ncrunchproject

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

5
.ncrunch/RemoteTest.v3.ncrunchproject

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

8
.travis.yml

@ -1,17 +1,17 @@
language: csharp
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
- 5.2.0
dotnet: 2.1.200
script:
- ./build.sh --target "Travis" --platform "Mono" --configuration "Release"
- ./build.sh --target "Travis" --platform "NetCoreOnly" --configuration "Release"
notifications:
email: false
webhooks:

1510
Avalonia.sln

File diff suppressed because it is too large

1
Avalonia.sln.DotSettings

@ -1,4 +1,5 @@
<wpf:ResourceDictionary xml:space="preserve" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:s="clr-namespace:System;assembly=mscorlib" xmlns:ss="urn:shemas-jetbrains-com:settings-storage-xaml" xmlns:wpf="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<s:Boolean x:Key="/Default/CodeInspection/ExcludedFiles/FileMasksToSkip/=_002A_002Examl/@EntryIndexedValue">True</s:Boolean>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=3E53A01A_002DB331_002D47F3_002DB828_002D4A5717E77A24_002Fd_003Aglass/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=6417B24E_002D49C2_002D4985_002D8DB2_002D3AB9D898EC91/@EntryIndexedValue">ExplicitlyExcluded</s:String>
<s:String x:Key="/Default/CodeInspection/ExcludedFiles/FilesAndFoldersToSkip2/=E3A1060B_002D50D0_002D44E8_002D88B6_002DF44EF2E5BD72_002Ff_003Ahtml_002Ehtm/@EntryIndexedValue">ExplicitlyExcluded</s:String>

22
appveyor.yml

@ -1,35 +1,24 @@
os: Visual Studio 2017
platform:
- Any CPU
skip_branch_with_pr: true
configuration:
- Release
environment:
DOTNET_SKIP_FIRST_TIME_EXPERIENCE: 1
DOTNET_CLI_TELEMETRY_OPTOUT: 1
NUGET_API_KEY:
secure: Xv89dlP2MSBZKhl1nrWSxqcDgCXB0HRhOd4SWQ+jRJ7QoLxQel5mLTipXM++J3G5
NUGET_API_URL: https://www.nuget.org/api/v2/package
MYGET_API_KEY:
secure: OtVfyN3ErqQrDTnWH2HDfJDlCiu/i4/X4wFmK3ZXXP7HmCiXYPSbTjMPwwdOxRaK
MYGET_API_URL: https://www.myget.org/F/avalonia-ci/api/v2/package
init:
- ps: (New-Object Net.WebClient).DownloadFile('https://raw.githubusercontent.com/appveyor/ci/master/scripts/xamarin-vs2017-151-fixed.targets', "C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Microsoft.Common.Targets\ImportAfter\Xamarin.Common.targets")
- 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"
- 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
- 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 "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"
- ps: .\build.ps1 -Target "AppVeyor" -Configuration "$env:configuration"
test: off
artifacts:
@ -37,5 +26,4 @@ artifacts:
- path: artifacts\zip\*.zip
- path: artifacts\inspectcode.xml
cache:
- gtk-sharp-2.12.26.msi
- dotnet-1.0.1.exe
- dotnet-2.0.0.exe

339
build.cake

@ -2,17 +2,16 @@
// ADDINS
///////////////////////////////////////////////////////////////////////////////
#addin "nuget:?package=Polly&version=4.2.0"
#addin "nuget:?package=NuGet.Core&version=2.12.0"
#tool "nuget:https://dotnet.myget.org/F/nuget-build/?package=NuGet.CommandLine&version=4.3.0-preview1-3980&prerelease"
#tool "nuget:?package=JetBrains.dotMemoryUnit&version=2.3.20160517.113140"
#tool "JetBrains.ReSharper.CommandLineTools"
#addin "nuget:?package=Polly&version=5.3.1"
#addin "nuget:?package=NuGet.Core&version=2.14.0"
#tool "nuget:?package=NuGet.CommandLine&version=4.3.0"
#tool "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2017.1.20170613.162720"
///////////////////////////////////////////////////////////////////////////////
// TOOLS
///////////////////////////////////////////////////////////////////////////////
#tool "nuget:?package=xunit.runner.console&version=2.2.0"
#tool "nuget:?package=OpenCover"
#tool "nuget:?package=xunit.runner.console&version=2.3.1"
#tool "nuget:?package=JetBrains.dotMemoryUnit&version=3.0.20171219.105559"
///////////////////////////////////////////////////////////////////////////////
// USINGS
@ -36,20 +35,31 @@ using NuGet;
// PARAMETERS
//////////////////////////////////////////////////////////////////////
Parameters parameters = new Parameters(Context);
Packages packages = new Packages(Context, parameters);
class AvaloniaBuildData
{
public AvaloniaBuildData(Parameters parameters, Packages packages)
{
Parameters = parameters;
Packages = packages;
}
public Parameters Parameters { get; }
public Packages Packages { get; }
}
///////////////////////////////////////////////////////////////////////////////
// SETUP
///////////////////////////////////////////////////////////////////////////////
Setup(context =>
Setup<AvaloniaBuildData>(context =>
{
Information("Building version {0} of Avalonia ({1}, {2}, {3}) using version {4} of Cake.",
var parameters = new Parameters(context);
var buildContext = new AvaloniaBuildData(parameters, new Packages(context, parameters));
Information("Building version {0} of Avalonia ({1}, {2}) using version {3} of Cake.",
parameters.Version,
parameters.Platform,
parameters.Configuration,
parameters.Target,
typeof(ICakeContext).Assembly.GetName().Version.ToString());
if (parameters.IsRunningOnAppVeyor)
@ -57,8 +67,7 @@ Setup(context =>
Information("Repository Name: " + BuildSystem.AppVeyor.Environment.Repository.Name);
Information("Repository Branch: " + BuildSystem.AppVeyor.Environment.Repository.Branch);
}
Information("Target: " + parameters.Target);
Information("Target:" + context.TargetTask.Name);
Information("Platform: " + parameters.Platform);
Information("Configuration: " + parameters.Configuration);
Information("IsLocalBuild: " + parameters.IsLocalBuild);
@ -72,13 +81,15 @@ Setup(context =>
Information("IsReleasable: " + parameters.IsReleasable);
Information("IsMyGetRelease: " + parameters.IsMyGetRelease);
Information("IsNuGetRelease: " + parameters.IsNuGetRelease);
return buildContext;
});
///////////////////////////////////////////////////////////////////////////////
// TEARDOWN
///////////////////////////////////////////////////////////////////////////////
Teardown(context =>
Teardown<AvaloniaBuildData>((context, buildContext) =>
{
Information("Finished running tasks.");
});
@ -88,20 +99,19 @@ Teardown(context =>
///////////////////////////////////////////////////////////////////////////////
Task("Clean")
.Does(() =>
.Does<AvaloniaBuildData>(data =>
{
CleanDirectories(parameters.BuildDirs);
CleanDirectory(parameters.ArtifactsDir);
CleanDirectory(parameters.NugetRoot);
CleanDirectory(parameters.ZipRoot);
CleanDirectory(parameters.BinRoot);
CleanDirectory(parameters.TestsRoot);
CleanDirectories(data.Parameters.BuildDirs);
CleanDirectory(data.Parameters.ArtifactsDir);
CleanDirectory(data.Parameters.NugetRoot);
CleanDirectory(data.Parameters.ZipRoot);
CleanDirectory(data.Parameters.BinRoot);
});
Task("Restore-NuGet-Packages")
.IsDependentOn("Clean")
.WithCriteria(parameters.IsRunningOnWindows)
.Does(() =>
.WithCriteria<AvaloniaBuildData>((context, data) => data.Parameters.IsRunningOnWindows)
.Does<AvaloniaBuildData>(data =>
{
var maxRetryCount = 5;
var toolTimeout = 2d;
@ -118,181 +128,162 @@ Task("Restore-NuGet-Packages")
toolTimeout+=0.5;
}})
.Execute(()=> {
NuGetRestore(parameters.MSBuildSolution, new NuGetRestoreSettings {
ToolPath = "./tools/NuGet.CommandLine/tools/NuGet.exe",
NuGetRestore(data.Parameters.MSBuildSolution, new NuGetRestoreSettings {
ToolTimeout = TimeSpan.FromMinutes(toolTimeout)
});
});
});
void DotNetCoreBuild()
void DotNetCoreBuild(Parameters parameters)
{
DotNetCoreRestore("samples\\ControlCatalog.NetCore");
DotNetBuild("samples\\ControlCatalog.NetCore");
}
var settings = new DotNetCoreBuildSettings
{
Configuration = parameters.Configuration,
MSBuildSettings = new DotNetCoreMSBuildSettings(),
};
Task("DotNetCoreBuild")
.IsDependentOn("Clean")
.Does(() => DotNetCoreBuild());
settings.MSBuildSettings.SetConfiguration(parameters.Configuration);
settings.MSBuildSettings.WithProperty("Platform", "\"" + parameters.Platform + "\"");
DotNetCoreBuild(parameters.MSBuildSolution, settings);
}
Task("Build")
.IsDependentOn("Restore-NuGet-Packages")
.Does(() =>
.Does<AvaloniaBuildData>(data =>
{
if(parameters.IsRunningOnWindows)
if(data.Parameters.IsRunningOnWindows)
{
MSBuild(parameters.MSBuildSolution, settings => {
settings.SetConfiguration(parameters.Configuration);
settings.WithProperty("Platform", "\"" + parameters.Platform + "\"");
settings.WithProperty("UseRoslynPathHack", "true");
MSBuild(data.Parameters.MSBuildSolution, settings => {
settings.SetConfiguration(data.Parameters.Configuration);
settings.SetVerbosity(Verbosity.Minimal);
settings.WithProperty("Windows", "True");
settings.WithProperty("Platform", "\"" + data.Parameters.Platform + "\"");
settings.WithProperty("UseRoslynPathHack", "true");
settings.UseToolVersion(MSBuildToolVersion.VS2017);
settings.WithProperty("Windows", "True");
settings.SetNodeReuse(false);
settings.SetMaxCpuCount(0);
});
}
else
{
DotNetCoreBuild();
DotNetCoreBuild(data.Parameters);
}
});
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(parameters.IsRunningOnWindows)
frameworks.Add("net461");
if(!project.EndsWith(".csproj"))
project = System.IO.Path.Combine(project, System.IO.Path.GetFileName(project)+".csproj");
Information("Running tests from " + project);
var frameworks = new List<string>(){"netcoreapp2.0"};
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"),
DotNetCoreTest(project,
new DotNetCoreTestSettings {
Configuration = parameters.Configuration,
Framework = fw
Framework = fw,
NoBuild = true,
NoRestore = true
});
}
}
Task("Run-Net-Core-Unit-Tests")
.IsDependentOn("Clean")
.Does(() => {
RunCoreTest("./tests/Avalonia.Base.UnitTests", parameters, false);
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);
Task("Run-Unit-Tests")
.IsDependentOn("Build")
.WithCriteria<AvaloniaBuildData>((context, data) => !data.Parameters.SkipTests)
.Does<AvaloniaBuildData>(data => {
RunCoreTest("./tests/Avalonia.Base.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Controls.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Input.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Interactivity.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Layout.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Markup.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Markup.Xaml.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Styling.UnitTests", data.Parameters, false);
RunCoreTest("./tests/Avalonia.Visuals.UnitTests", data.Parameters, false);
if (data.Parameters.IsRunningOnWindows)
{
RunCoreTest("./tests/Avalonia.Direct2D1.UnitTests", data.Parameters, true);
}
});
Task("Run-Unit-Tests")
.IsDependentOn("Run-Net-Core-Unit-Tests")
Task("Run-Designer-Tests")
.IsDependentOn("Build")
.WithCriteria(() => !parameters.SkipTests)
.Does(() =>
{
if(!parameters.IsRunningOnWindows)
return;
.WithCriteria<AvaloniaBuildData>((context, data) => !data.Parameters.SkipTests)
.Does<AvaloniaBuildData>(data => {
RunCoreTest("./tests/Avalonia.DesignerSupport.Tests", data.Parameters, false);
});
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))
.Select(name => MakeAbsolute(File("./tests/" + name + "/bin/" + parameters.DirSuffix + "/" + name + ".dll")))
.ToList();
Task("Run-Render-Tests")
.IsDependentOn("Build")
.WithCriteria<AvaloniaBuildData>((context, data) => !data.Parameters.SkipTests && data.Parameters.IsRunningOnWindows)
.Does<AvaloniaBuildData>(data => {
RunCoreTest("./tests/Avalonia.Skia.RenderTests/Avalonia.Skia.RenderTests.csproj", data.Parameters, true);
RunCoreTest("./tests/Avalonia.Direct2D1.RenderTests/Avalonia.Direct2D1.RenderTests.csproj", data.Parameters, true);
});
if (parameters.IsRunningOnWindows)
Task("Run-Leak-Tests")
.WithCriteria<AvaloniaBuildData>((context, data) => !data.Parameters.SkipTests && data.Parameters.IsRunningOnWindows)
.IsDependentOn("Build")
.Does(() =>
{
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";
var xUnitSettings = new XUnit2Settings
{
ToolPath = toolPath,
Parallelism = ParallelismOption.None,
ShadowCopy = false
};
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;
var dotMemoryUnit = Context.Tools.Resolve("dotMemoryUnit.exe");
var leakTestsExitCode = StartProcess(dotMemoryUnit, new ProcessSettings
{
Arguments = new ProcessArgumentBuilder()
.Append(Context.Tools.Resolve("xunit.console.x86.exe").FullPath)
.Append("--propagate-exit-code")
.Append("--")
.Append("tests\\Avalonia.LeakTests\\bin\\Release\\net461\\Avalonia.LeakTests.dll"),
Timeout = 120000
});
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)
{
testsInDirectoryToRun.AddRange(GetFiles("./artifacts/tests/*Tests.dll"));
}
else
{
testsInDirectoryToRun.AddRange(GetFiles("./artifacts/tests/*.UnitTests.dll"));
}
if (leakTestsExitCode != 0)
{
throw new Exception("Leak Tests failed");
}
});
if(parameters.IsRunningOnWindows)
{
OpenCover(context => {
context.XUnit2(testsInDirectoryToRun, xUnitSettings);
}, openCoverOutput, openCoverSettings);
}
else
{
XUnit2(testsInDirectoryToRun, xUnitSettings);
}
});
Task("Run-Tests")
.IsDependentOn("Run-Unit-Tests")
.IsDependentOn("Run-Render-Tests")
.IsDependentOn("Run-Designer-Tests")
.IsDependentOn("Run-Leak-Tests");
Task("Copy-Files")
.IsDependentOn("Run-Unit-Tests")
.Does(() =>
.IsDependentOn("Run-Tests")
.Does<AvaloniaBuildData>(data =>
{
CopyFiles(packages.BinFiles, parameters.BinRoot);
CopyFiles(data.Packages.BinFiles, data.Parameters.BinRoot);
});
Task("Zip-Files")
.IsDependentOn("Copy-Files")
.Does(() =>
.Does<AvaloniaBuildData>(data =>
{
Zip(parameters.BinRoot, parameters.ZipCoreArtifacts);
Zip(parameters.ZipSourceControlCatalogDesktopDirs,
parameters.ZipTargetControlCatalogDesktopDirs,
GetFiles(parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dll") +
GetFiles(parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.config") +
GetFiles(parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.so") +
GetFiles(parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dylib") +
GetFiles(parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.exe"));
Zip(data.Parameters.BinRoot, data.Parameters.ZipCoreArtifacts);
Zip(data.Parameters.ZipSourceControlCatalogDesktopDirs,
data.Parameters.ZipTargetControlCatalogDesktopDirs,
GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dll") +
GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.config") +
GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.so") +
GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.dylib") +
GetFiles(data.Parameters.ZipSourceControlCatalogDesktopDirs.FullPath + "/*.exe"));
});
Task("Create-NuGet-Packages")
.IsDependentOn("Run-Unit-Tests")
.IsDependentOn("Run-Tests")
.IsDependentOn("Inspect")
.Does(() =>
.Does<AvaloniaBuildData>(data =>
{
foreach(var nuspec in packages.NuspecNuGetSettings)
foreach(var nuspec in data.Packages.NuspecNuGetSettings)
{
NuGetPack(nuspec);
}
@ -300,12 +291,12 @@ Task("Create-NuGet-Packages")
Task("Publish-MyGet")
.IsDependentOn("Create-NuGet-Packages")
.WithCriteria(() => !parameters.IsLocalBuild)
.WithCriteria(() => !parameters.IsPullRequest)
.WithCriteria(() => parameters.IsMainRepo)
.WithCriteria(() => parameters.IsMasterBranch)
.WithCriteria(() => parameters.IsMyGetRelease)
.Does(() =>
.WithCriteria<AvaloniaBuildData>((context, data) => !data.Parameters.IsLocalBuild)
.WithCriteria<AvaloniaBuildData>((context, data) => !data.Parameters.IsPullRequest)
.WithCriteria<AvaloniaBuildData>((context, data) => data.Parameters.IsMainRepo)
.WithCriteria<AvaloniaBuildData>((context, data) => data.Parameters.IsMasterBranch)
.WithCriteria<AvaloniaBuildData>((context, data) => data.Parameters.IsMyGetRelease)
.Does<AvaloniaBuildData>(data =>
{
var apiKey = EnvironmentVariable("MYGET_API_KEY");
if(string.IsNullOrEmpty(apiKey))
@ -319,7 +310,7 @@ Task("Publish-MyGet")
throw new InvalidOperationException("Could not resolve MyGet API url.");
}
foreach(var nupkg in packages.NugetPackages)
foreach(var nupkg in data.Packages.NugetPackages)
{
NuGetPush(nupkg, new NuGetPushSettings {
Source = apiUrl,
@ -334,11 +325,11 @@ Task("Publish-MyGet")
Task("Publish-NuGet")
.IsDependentOn("Create-NuGet-Packages")
.WithCriteria(() => !parameters.IsLocalBuild)
.WithCriteria(() => !parameters.IsPullRequest)
.WithCriteria(() => parameters.IsMainRepo)
.WithCriteria(() => parameters.IsNuGetRelease)
.Does(() =>
.WithCriteria<AvaloniaBuildData>((context, data) => !data.Parameters.IsLocalBuild)
.WithCriteria<AvaloniaBuildData>((context, data) => !data.Parameters.IsPullRequest)
.WithCriteria<AvaloniaBuildData>((context, data) => data.Parameters.IsMainRepo)
.WithCriteria<AvaloniaBuildData>((context, data) => data.Parameters.IsNuGetRelease)
.Does<AvaloniaBuildData>(data =>
{
var apiKey = EnvironmentVariable("NUGET_API_KEY");
if(string.IsNullOrEmpty(apiKey))
@ -352,7 +343,7 @@ Task("Publish-NuGet")
throw new InvalidOperationException("Could not resolve NuGet API url.");
}
foreach(var nupkg in packages.NugetPackages)
foreach(var nupkg in data.Packages.NugetPackages)
{
NuGetPush(nupkg, new NuGetPushSettings {
ApiKey = apiKey,
@ -366,18 +357,22 @@ Task("Publish-NuGet")
});
Task("Inspect")
.WithCriteria(parameters.IsRunningOnWindows)
.WithCriteria<AvaloniaBuildData>((context, data) => data.Parameters.IsRunningOnWindows)
.IsDependentOn("Restore-NuGet-Packages")
.Does(() =>
{
var badIssues = new []{"PossibleNullReferenceException"};
var whitelist = new []{"tests", "src\\android", "src\\ios",
"src\\windows\\avalonia.designer", "src\\avalonia.htmlrenderer\\external"};
"src\\markup\\avalonia.markup.xaml\\portablexaml\\portable.xaml.github"};
Information("Running code inspections");
StartProcess("tools\\JetBrains.ReSharper.CommandLineTools\\tools\\inspectcode.exe",
new ProcessSettings{ Arguments = "--output=artifacts\\inspectcode.xml --profile=Avalonia.sln.DotSettings Avalonia.sln" });
var exitCode = StartProcess(Context.Tools.Resolve("inspectcode.exe"),
new ProcessSettings
{
Arguments = "--output=artifacts\\inspectcode.xml --profile=Avalonia.sln.DotSettings Avalonia.sln",
RedirectStandardOutput = true
});
Information("Analyzing report");
var doc = XDocument.Parse(System.IO.File.ReadAllText("artifacts\\inspectcode.xml"));
var failBuild = false;
@ -405,23 +400,23 @@ Task("Inspect")
Task("Package")
.IsDependentOn("Create-NuGet-Packages");
Task("Default").Does(() =>
{
if(parameters.IsRunningOnWindows)
RunTarget("Package");
else
RunTarget("Run-Net-Core-Unit-Tests");
});
Task("AppVeyor")
.IsDependentOn("Zip-Files")
.IsDependentOn("Publish-MyGet")
.IsDependentOn("Publish-NuGet");
Task("Travis")
.IsDependentOn("Run-Net-Core-Unit-Tests");
.IsDependentOn("Run-Tests");
///////////////////////////////////////////////////////////////////////////////
// EXECUTE
///////////////////////////////////////////////////////////////////////////////
RunTarget(parameters.Target);
var target = Context.Argument("target", "Default");
if (target == "Default")
{
target = Context.IsRunningOnWindows() ? "Package" : "Run-Tests";
}
RunTarget(target);

2
build.ps1

@ -46,7 +46,7 @@ http://cakebuild.net
Param(
[string]$Script = "build.cake",
[string]$Target = "Default",
[ValidateSet("Any CPU", "x86", "x64", "Mono", "iPhone")]
[ValidateSet("Any CPU", "x86", "x64", "NetCoreOnly", "iPhone")]
[string]$Platform = "Any CPU",
[ValidateSet("Release", "Debug")]
[string]$Configuration = "Release",

5
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>

8
build/Binding.props

@ -0,0 +1,8 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="System.ComponentModel.Annotations" 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" />
</ItemGroup>
</Project>

11
build/EmbedXaml.props

@ -0,0 +1,11 @@
<Project DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Compile Update="**\*.xaml.cs">
<DependentUpon>%(Filename)</DependentUpon>
</Compile>
<EmbeddedResource Include="**\*.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
</Project>

2
build/JetBrains.dotMemoryUnit.props

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

2
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
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>

5
build/MonoMac.props

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

2
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.25" />
<PackageReference Include="Moq" Version="4.7.99" />
</ItemGroup>
</Project>

2
build/NetCore.props

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

6
build/NetFX.props

@ -0,0 +1,6 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition=" '$(TargetFramework)' == 'net461' and '$(OS)' == 'Unix' ">
<FrameworkPathOverride>/usr/lib/mono/4.6.1-api</FrameworkPathOverride>
<FrameworkPathOverride Condition="$([MSBuild]::IsOsPlatform('OSX'))">/Library/Frameworks/Mono.framework/Versions/Current/lib/mono/4.6.1-api</FrameworkPathOverride>
</PropertyGroup>
</Project>

5
build/ReactiveUI.props

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

12
build/Rx.props

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

13
build/SampleApp.props

@ -0,0 +1,13 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(TargetFramework)'=='net461'" >
<OutputType>WinExe</OutputType>
</PropertyGroup>
<!-- Should be a Condition="'$(TargetFramework)'=='net461'" here but that doesn't work due
to https://github.com/dotnet/sdk/issues/1227 -->
<ItemGroup>
<ProjectReference Include="..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" />
<ProjectReference Include="..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" />
</ItemGroup>
<Import Condition="'$(TargetFramework)'=='net461'" Project="SharpDX.props" />
</Project>

5
build/Serilog.Sinks.Trace.props

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

4
build/Serilog.props

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

14
build/SharedVersion.props

@ -0,0 +1,14 @@
<Project DefaultTargets="Build"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Product>Avalonia</Product>
<Version>0.6.2</Version>
<Copyright>Copyright 2016 &#169; The AvaloniaUI Project</Copyright>
<PackageLicenseUrl>https://github.com/AvaloniaUI/Avalonia/blob/master/licence.md</PackageLicenseUrl>
<PackageProjectUrl>https://github.com/AvaloniaUI/Avalonia/</PackageProjectUrl>
<RepositoryUrl>https://github.com/AvaloniaUI/Avalonia/</RepositoryUrl>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
<NoWarn>CS1591</NoWarn>
<LangVersion>latest</LangVersion>
</PropertyGroup>
</Project>

9
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>

2
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>

5
build/SourceLink.props

@ -0,0 +1,5 @@
<Project>
<ItemGroup>
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.0" PrivateAssets="All" />
</ItemGroup>
</Project>

5
build/Splat.props

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

5
build/System.Drawing.Common.props

@ -0,0 +1,5 @@
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<PackageReference Include="System.Drawing.Common" Version="4.5.0-preview1-25914-04" />
</ItemGroup>
</Project>

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>

19
build/XUnit.props

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

15
cake.config

@ -0,0 +1,15 @@
; This is the default configuration file for Cake.
; This file was downloaded from https://github.com/cake-build/resources
[Nuget]
Source=https://api.nuget.org/v3/index.json
UseInProcessClient=true
LoadDependencies=false
[Paths]
Tools=./tools
Addins=./tools/Addins
Modules=./tools/Modules
[Settings]
SkipVerification=false

3
docs/.gitignore

@ -1,3 +0,0 @@
#docfx
_site
api

21
docs/README.md

@ -1,21 +0,0 @@
# Avalonia Documentation
* [API Reference](http://avalonia.github.io/)
## Building
Download and unzip `docfx.zip` into `Documentation` folder from [DocFX project site](https://github.com/dotnet/docfx/releases).
**Step 1.** To create `_site` documentation folder run build script
```
build.cmd
```
**Step 2.** To browse `_site` documentation folder run serve script
```
serve.cmd
```
And you can view the generated website in your browser `http://localhost:8080`.

3
docs/build.cmd

@ -1,3 +0,0 @@
@echo off
docfx metadata
docfx build

55
docs/docfx.json

@ -1,55 +0,0 @@
{
"metadata": [
{
"src": [
{
"files": [
"/src/Gtk/Avalonia.Cairo/Avalonia.Cairo.csproj",
"/src/Gtk/Avalonia.Gtk/Avalonia.Gtk.csproj",
"/src/Markup/Avalonia.Markup/Avalonia.Markup.csproj",
"/src/Markup/Avalonia.Markup.Xaml/Avalonia.Markup.Xaml.csproj",
"/src/Avalonia.Animation/Avalonia.Animation.csproj",
"/src/Avalonia.Application/Avalonia.Application.csproj",
"/src/Avalonia.Base/Avalonia.Base.csproj",
"/src/Avalonia.Controls/Avalonia.Controls.csproj",
"/src/Avalonia.Diagnostics/Avalonia.Diagnostics.csproj",
"/src/Avalonia.HtmlRenderer/Avalonia.HtmlRenderer.csproj",
"/src/Avalonia.Input/Avalonia.Input.csproj",
"/src/Avalonia.Interactivity/Avalonia.Interactivity.csproj",
"/src/Avalonia.Layout/Avalonia.Layout.csproj",
"/src/Avalonia.ReactiveUI/Avalonia.ReactiveUI.csproj",
"/src/Avalonia.Visuals/Avalonia.Visuals.csproj",
"/src/Avalonia.Styling/Avalonia.Styling.csproj",
"/src/Avalonia.Themes.Default/Avalonia.Themes.Default.csproj",
"/src/Skia/Avalonia.Skia.Desktop/Avalonia.Skia.Desktop.csproj",
"/src/Windows/Avalonia.Designer/Avalonia.Designer.csproj",
"/src/Windows/Avalonia.Direct2D1/Avalonia.Direct2D1.csproj",
"/src/Windows/Avalonia.Win32/Avalonia.Win32.csproj",
],
"exclude": [ "**/bin/**", "**/obj/**" ],
"cwd": ".."
}
],
"dest": "api"
},
],
"build": {
"content":
[
{
"files": ["**/*.yml", "index.md", "tutorial/*.md", "guidelines/*.md", "spec/*.md"],
}
],
"resource": [
{
"files": ["images/**", "tutorial/images/**", "guidelines/images/**", "spec/images/**"]
}
],
"overwrite": "apidoc/*.md",
"globalMetadata": {
"_appTitle": "Avalonia Website"
},
"dest": "_site",
"template": [ "default", "template"]
}
}

89
docs/guidelines/build.md

@ -1,89 +0,0 @@
# Building Avalonia
## Windows
Avalonia requires at least Visual Studio 2017 to build on Windows.
### Install GTK Sharp
For the moment under windows, you must have [gtk-sharp](http://www.mono-project.com/download/#download-win)
installed. Note that after installing the package your machine may require a restart before GTK# is
added to your path. We hope to remove or make this dependency optional at some point in the future.
### Clone the Avalonia repository
```
git clone https://github.com/AvaloniaUI/Avalonia.git
git submodule update --init
```
### Open in Visual Studio
Open the `Avalonia.sln` solution in Visual Studio 2015 or newer. The free Visual Studio Community
edition works fine. Run the `Samples\ControlCatalog.Desktop` project to see the sample application.
## Linux
### Install the latest version of Mono
To build Avalonia under Linux, you need to have a recent version of Mono installed. Mono is a cross-
platform, open source .Net platform. There is a very good chance that the version of Mono that came
with your Linux distribution is too old, so you want to install a more up-to-date version. The most
convenient way to to this is through your package manager. The Mono project has great [installation
instructions for many popular Linux distros](http://www.mono-project.com/docs/getting-started/install/linux).
This will make the most up-to-date Mono release available through your package manager, and offer
you updates as they become available.
Once you have your package manager configured for the Mono repository, install the `mono-devel`
package, for example on ubuntu:
```
sudo apt-get install mono-devel
```
Once installed, check the version of mono to ensure it's at least 4.4.2:
```
mono --version
```
### Clone the Avalonia repository
```
git clone https://github.com/AvaloniaUI/Avalonia.git
git submodule update --init
```
### Restore nuget packages
```
cd Avalonia
mkdir -p .nuget
wget -O .nuget/nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
mono .nuget/nuget.exe restore Avalonia.sln
```
### Build and Run Avalonia
To build Avalonia in the `Debug` configuration:
```
xbuild /p:Platform=Mono /p:Configuration=Debug Avalonia.sln
```
You should now be able to run the ControlCatalog.Desktop sample:
```
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.
Finally, select the `Debug | Mono` or `Release | Mono` build configuration and you should be good to
go!

60
docs/guidelines/contributing.md

@ -1,60 +0,0 @@
# Contributing #
## Before You Start ##
Drop into our [gitter chat room](https://gitter.im/Avalonia/Avalonia) and let us know what you're thinking of doing. We might be able to give you guidance or let you know if someone else is already working on the feature.
## Style ##
The codebase uses [.net core](https://github.com/dotnet/corefx/blob/master/Documentation/coding-guidelines/coding-style.md) coding style.
Try to keep lines of code around 100 characters in length or less, though this is not a hard limit.
If you're a few characters over then don't worry too much.
**DO NOT USE #REGIONS** full stop.
## Pull requests ##
A single pull request should be submitted for each change. If you're making more than one change,
please submit separate pull requests for each change for easy review. Rebase your changes to make
sense, so a history that looks like:
* Add class A
* Feature A didn't set Foo when Bar was set
* Fix spacing
* Add class B
* Sort using statements
Should be rebased to read:
* Add class A
* Add class B
Again, this makes review much easier.
Please try not to submit pull requests that don't add new features (e.g. moving stuff around)
unless you see something that is obviously wrong or that could be written in a more terse or
idiomatic style. It takes time to review each pull request - time that I'd prefer to spend writing
new features!
Prefer terseness to verbosity but don't try to be too clever.
## Tests ##
There are two types of tests currently in the codebase; unit tests and render tests.
Unit tests should be contained in a class name that mirrors the class being tested with the suffix
-Tests, e.g.
Avalonia.Controls.UnitTests.Presenters.TextPresenterTests
Where Avalonia.Controls.UnitTests is the name of the project.
Unit test methods should be named in a sentence style, separated by underscores, that describes in
English what the test is testing, e.g.
void Calling_Foo_Should_Increment_Bar()
Render tests should describe what the produced image is:
void Rectangle_2px_Stroke_Filled()

4
docs/guidelines/toc.yml

@ -1,4 +0,0 @@
- name: Building Avalonia
href: build.md
- name: Contributing
href: contributing.md

BIN
docs/images/avalonia-video.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 133 KiB

BIN
docs/images/cross-platform.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

BIN
docs/images/hello-world-xaml.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 122 KiB

BIN
docs/images/inspection-support.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 226 KiB

BIN
docs/images/screen.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 27 KiB

37
docs/index.md

@ -1,37 +0,0 @@
# The Avalonia UI Framework
Cross platform .NET UI Framework with bindings and XAML
## Current status
We're pleased to announce that Avalonia is now in alpha!
What does alpha mean? Well, it means that it's now at a stage where you can have a play and hopefully create simple applications. There's now a Visual Studio Extension containing project and item templates that will help you get started, and there's an initial complement of controls. There's still a lot missing, and you will find bugs, and the API will change, but this represents the first time where we've made it somewhat easy to have a play and experiment with the framework.
## How do I try it out
The easiest way to try out Avalonia is to install the [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio).
This will add a Avalonia project template and a Window template to the standard Visual Studo "Add" dialog (yes, icons still to come :) ):
![](images/add-dialogs.png)
Creating a Avalonia Project will give you a simple project with a single XAML window. We even have a simple designer:
![](images/hello-world-xaml.png)
You can also find the project [on GitHub](https://github.com/AvaloniaUI/Avalonia/)
## News
You can read news about Avalonia on [Groky's blog](http://grokys.github.io/)
## Cross Platform
Fow now we can run on Windows, Linux and Mac.
![](images/cross-platform.png)
## Inspection support
![](images/inspection-support.png)

225
docs/intro.md

@ -1,225 +0,0 @@
# Avalonia #
...a next generation WPF?
## Background ##
As everyone who's involved in client-side .NET development knows, the past half decade have been a
very sad time. Where WPF started off as a game-changer, it now seems to have been all but forgotten.
WinRT came along and took many of the lessons of WPF but it's currently not usable on the desktop.
After a few months of trying to reverse-engineer WPF with the [Avalonia Project](https://github.com/grokys/Avalonia) I began to come to the same conclusion that I imagine Microsoft
came to internally: for all its groundbreaking-ness at the time, WPF at its core is a dated mess,
written for .NET 1 and barely updated to even bring it up-to-date with .NET 2 features such as
generics.
So I began to think: what if we were to start anew with modern C# features such as *(gasp)*
Generics, Observables, async, etc etc. The result of that thought is Avalonia
(https://github.com/grokys/Avalonia).
##### DISCLAIMER
This is really **early development pre-alpha-alpha** stuff. Everything is subject to
change, I'm not even sure if the performance characteristics of Rx make Observables suitable for
binding throughout a framework. *I'm writing this only to see if the idea of exploring these ideas
appeals to anyone else.*
So what can it do so far? Not a whole lot right now. Here's the demo application:
![](screen.png)
## AvaloniaProperty ##
AvaloniaProperty is the equivalent of WPF's DependencyProperty.
I'm not a big fan of DependencyProperty. My first thought was that I'd rather not have something
like this at all and just use basic INPC but DPs give you two important features: Inheritance and
Attached Properties. So the challenge became to improve it.
Declaring a DependencyProperty in WPF looks something like this:
```csharp
public static readonly DependencyProperty PropertyDeclaration =
DependencyProperty.Register(
"PropertyName",
typeof(PropertyType),
typeof(OwnerClass),
new FrameworkPropertyMetadata(
default(PropertyType),
FrameworkPropertyMetadataOptions.Inherits));
public PropertyType PropertyName
{
get { return (PropertyType)this.GetValue(PropertyDeclaration); }
set { this.SetValue(PropertyDeclaration, value); }
}
```
Eww! All that just to declare a single property. There's **A LOT** of boilerplate there. With
generics and default parameters we can at least make it look a bit nicer:
```csharp
public static readonly AvaloniaProperty<PropertyType> PropertyDeclaration =
AvaloniaProperty.Register<OwnerClass, PropertyType>("PropertyName", inherits: true);
public PropertyType PropertyName
{
get { return this.GetValue(PropertyDeclaration); }
set { this.SetValue(PropertyDeclaration, value); }
}
```
What can we see here?
- AvaloniaProperties are typed, so no more having to cast in the getter.
- We pass the property type and owner class as a generic type to `Register()` so we don't have to
write `typeof()` twice.
- We used default parameter values in `Register()` so that defaults don't have to be restated.
*(ASIDE: maybe Roslyn will give us [var for fields](http://blogs.msdn.com/b/ericlippert/archive/2009/01/26/why-no-var-on-fields.aspx)...)? Lets hope...*
## Binding
Binding in Avalonia uses Reactive Extensions' [IObservable](http://msdn.microsoft.com/library/dd990377.aspx). To bind an IObservable to a property, use the `Bind()` method:
```csharp
control.Bind(BorderProperty, someObject.SomeObservable());
```
Note that because AvaloniaProperty is typed, we can check that the observable is of the correct type.
To get the value of a property as an observable, call `GetObservable()`:
```csharp
var observable = control.GetObservable(Control.FooProperty);
```
## Attached Properties and Binding Pt 2
Attached properties are set just like in WPF, using `SetValue()`. But what about the `[]` operator, also called [index initializer](https://roslyn.codeplex.com/wikipage?title=Language%20Feature%20Status&referringTitle=Home) (see *C# feature descriptions*)? The upcoming version of C# will provide a new feature that allows us to use `[]` array subscripts in object initializers. An example on how to make use of it will look like this:
```csharp
var control = new Control
{
Property1 = "Foo",
[Attached.Property] = "Bar",
}
```
Nice... Lets take this further:
```csharp
var control = new Control
{
Property1 = "Foo",
[Attached.Property] = "Bar",
[!Property2] = something.SomeObservable,
}
```
Yep, by putting a bang in front of the property name you can **bind** to a property (attached or
otherwise) from the object initializer.
Binding to a property on another control? Easy:
```csharp
var control = new Control
{
Property1 = "Foo",
[Attached.Property] = "Bar",
[!Property2] = anotherControl[!Property1],
}
```
Two way binding? Just add two bangs:
```csharp
var control = new Control
{
Property1 = "Foo",
[Attached.Property] = "Bar",
[!!Property2] = anotherControl[!!Property1],
}
```
## Visual and Logical trees
Avalonia uses the same visual/logical tree separation that is used by WPF (and to some extent HTML
is moving in this direction with the Shadow DOM). The manner of accessing the two trees is slightly
different however. Rather than using Visual/LogicalTreeHelper you can cast any control to an
`IVisual` or `ILogical` to reveal the tree operations. There's also the VisualExtensions class which
provides some useful extension methods such as `GetVisualAncestor<T>(this IVisual visual)` or
`GetVisualAt(this IVisual visual, Point p)`.
Again like WPF, Controls are lookless with the visual appearance being defined by the Template
property, which is determined by...
## Styles
Styles in Avalonia diverge from styles in WPF quite a lot, and move towards a more CSS-like system.
It's probably easiest to show in an example. Here is the default style for the CheckBox control:
```csharp
new Style(x => x.OfType<CheckBox>())
{
Setters = new[]
{
new Setter(Button.TemplateProperty, ControlTemplate.Create<CheckBox>(this.Template))
}
};
new Style(x => x.OfType<CheckBox>().Template().Id("checkMark"))
{
Setters = new[]
{
new Setter(Shape.IsVisibleProperty, false)
}
};
new Style(x => x.OfType<CheckBox>().Class(":checked").Template().Id("checkMark"))
{
Setters = new[]
{
new Setter(Shape.IsVisibleProperty, true)
}
};
```
Let's see what's happening here:
```csharp
new Style(x => x.OfType<CheckBox>())
```
The constructor for the Style class defines the selector. Here we're saying "*this style applies to
all controls in the the visual tree of type CheckBox*". A more complex selector:
```csharp
new Style(x => x.OfType<CheckBox>().Class(":checked").Template().Id("checkMark"))
```
This selector matches *"all controls with Id == "checkMark" in the template of a CheckBox with the
class `:checked`"*. Each control has an Id property, and Ids in templates are considered to be in a
separate namespace.
Inside the Style class we then have a collection of setters similar to WPF.
This system means that there's no more need for WPF's Triggers - the styling works with classes
(which are arbitrary strings) similar to CSS. Similar to CSS, classes with a leading `:` are set
by the control itself in response to events like `mouseover` and `click`.
Similar to WPF, styles can be defined on each control, with a global application style collection
at the root. This means that different subsections of the visual tree can have a completely
different look-and-feel.
## XAML
As you can see, all of the examples here are defined in code - but a XAML implementation is being
worked on. The current progress can be reviewed at [https://github.com/SuperJMN/Avalonia](https://github.com/SuperJMN/Avalonia).
## That's all for now
There's a lot more to see, and even more to do, so if you want to have a play you can get the code
here: [https://github.com/grokys/Avalonia](https://github.com/grokys/Avalonia)
Feedback is always welcome!

2
docs/serve.cmd

@ -1,2 +0,0 @@
@echo off
docfx serve _site

101
docs/spec/architecture.md

@ -1,101 +0,0 @@
# Avalonia Architecture
At the highest level, avalonia is split up into a "core" and two "subsystems".
* The core is a set of Portable Class Libraries that can run anywhere.
* The Windowing subsystem is responsible for creating windows, handling input and scheduling timers.
* The Rendering subsystem is responsible for drawing.
There are currently two Windowing and two Rendering subsystems:
## Windowing Subsystems
* Avalonia.Win32 uses the Win32 API (this also works on 64-bit windows).
* Avalonia.Gtk uses the GTK2 toolkit and can be run on both Windows and *nix.
## Rendering Subsystems
* Avalonia.Direct2D1 uses Microsoft's Direct2D1 API.
* Avalonia.Cairo uses Cairo for rendering and Pango for text layout.
## Core
The Avalonia core is split up into several assemblies. Note that they're not separated like this
because you will want to use them separately; they are separate to maintain separation of concerns
and a layered architecture. It is fully possible that they will be ILMerged into a single assembly
for distribution.
The assemblies are as follows, from lowest to highest level:
### Avalonia.Base
The main classes in this assembly are `AvaloniaObject` and `AvaloniaProperty`.
These are Avalonia's versions of XAML's `DependencyObject` and `DependencyProperty`. It also
defines a `AvaloniaDispatcher` which is - surprise - our version of XAML's `Dispatcher`.
### Avalonia.Animation
The main class in the assembly is `Animatable`.
Allows AvaloniaProperties to be animated and provides various utilities related to animation.
### Avalonia.Visuals
The main class in this assembly is `Visual` and its interface `IVisual`.
Defines the "Visual" layer which is a 2D scene graph, with each node being a `IVisual`/`Visual`.
Also defines primitives such as `Point`/`Rect`/`Matrix`, plus `Geometry`, `Bitmap`, `Brush` and
whatever else you might need in order to draw to the screen.
### Avalonia.Styling
The main interface in this assembly is `IStyleable`.
Defines a CSS-like system for styling controls.
### Avalonia.Layout
The main class in this assembly is `Layoutable`.
Defines a XAML-like layout system using `Measure` and `Arrange`. Also defines `LayoutManager` which
carries out the actual layout.
### Avalonia.Interactivity
The main class in this assembly is `Interactive`.
Defines a system of routed events similar to those found in XAML.
### Avalonia.Input
The main class in this assembly is `InputElement`.
Handles input from various devices such as `MouseDevice` and `KeyboardDevice`, together with
`FocusManager` for tracking input focus. Input is sent from the windowing subsystem to
`InputManager` in the form of "Raw" events which are then translated into routed events for the
controls.
### Avalonia.Controls
There are many important classes in this assembly, but the root of them is `Control`.
Finally defines the actual controls. The `Control` class is analogous to WPF's `FrameworkElement`
whereas the `TemplatedControl` class is our version of WPF's `Control`. This is also where you'll
find all of the basic controls you'd expect.
### Avalonia.Themes.Default
Defines a default theme using a set of styles and control templates.
### Avalonia.Application
The main class in this assembly is `Application`.
This ties everything together, setting up the service locator, defining the default theme etc.
### Avalonia.Diagnostics
Adds utilities for debugging avalonia applications, such as `DevTools` which provides a Snoop/WPF
Inspector/Browser DevTools window for inspecting the state of the application.

156
docs/spec/binding-from-code.md

@ -1,156 +0,0 @@
# Binding from Code
Avalonia binding from code works somewhat differently to WPF/UWP. At the low level, Avalonia's
binding system is based on Reactive Extensions' `IObservable` which is then built upon by XAML
bindings (which can also be instantiated in code).
## Binding to an observable
You can bind a property to an observable using the `AvaloniaObject.Bind` method:
```csharp
// We use an Rx Subject here so we can push new values using OnNext
var source = new Subject<string>();
var textBlock = new TextBlock();
// Bind TextBlock.Text to source
textBlock.Bind(TextBlock.TextProperty, source);
// Set textBlock.Text to "hello"
source.OnNext("hello");
// Set textBlock.Text to "world!"
source.OnNext("world!");
```
## Binding priorities
You can also pass a priority to a binding. *Note: Priorities only apply to styled properties: they*
*are ignored for direct properties.*
The priority is passed using the `BindingPriority` enum, which looks like this:
```csharp
/// <summary>
/// The priority of a binding.
/// </summary>
public enum BindingPriority
{
/// <summary>
/// A value that comes from an animation.
/// </summary>
Animation = -1,
/// <summary>
/// A local value: this is the default.
/// </summary>
LocalValue = 0,
/// <summary>
/// A triggered style binding.
/// </summary>
/// <remarks>
/// A style trigger is a selector such as .class which overrides a
/// <see cref="TemplatedParent"/> binding. In this way, a basic control can have
/// for example a Background from the templated parent which changes when the
/// control has the :pointerover class.
/// </remarks>
StyleTrigger,
/// <summary>
/// A binding to a property on the templated parent.
/// </summary>
TemplatedParent,
/// <summary>
/// A style binding.
/// </summary>
Style,
/// <summary>
/// The binding is uninitialized.
/// </summary>
Unset = int.MaxValue,
}
```
Bindings with a priority with a smaller number take precedence over bindings with a higher value
priority, and bindings added more recently take precedence over other bindings with the same
priority. Whenever the binding produces `AvaloniaProperty.UnsetValue` then the next binding in the
priority order is selected.
## Setting a binding in an object initializer
It is often useful to set up bindings in object initializers. You can do this using the indexer:
```csharp
var source = new Subject<string>();
var textBlock = new TextBlock
{
Foreground = Brushes.Red,
MaxWidth = 200,
[!TextBlock.TextProperty] = source.ToBinding(),
};
```
Using this method you can also easily bind a property on one control to a property on another:
```csharp
var textBlock1 = new TextBlock();
var textBlock2 = new TextBlock
{
Foreground = Brushes.Red,
MaxWidth = 200,
[!TextBlock.TextProperty] = textBlock1[!TextBlock.TextProperty],
};
```
Of course the indexer can be used outside object initializers too:
```csharp
textBlock2[!TextBlock.TextProperty] = textBlock1[!TextBlock.TextProperty];
```
# Transforming binding values
Because we're working with observables, we can easily transform the values we're binding!
```csharp
var source = new Subject<string>();
var textBlock = new TextBlock
{
Foreground = Brushes.Red,
MaxWidth = 200,
[!TextBlock.TextProperty] = source.Select(x => "Hello " + x).ToBinding(),
};
```
# Using XAML bindings from code
Sometimes when you want the additional features that XAML bindings provide, it's easier to use XAML bindings from code. For example, using only observables you could bind to a property on `DataContext` like this:
```csharp
var textBlock = new TextBlock();
var viewModelProperty = textBlock.GetObservable(TextBlock.DataContext)
.OfType<MyViewModel>()
.Select(x => x?.Name);
textBlock.Bind(TextBlock, viewModelProperty);
```
However, it might be preferable to use a XAML binding in this case:
```csharp
var textBlock = new TextBlock
{
[!TextBlock.TextProperty] = new Binding("Name")
};
```
By using XAML binding objects, you get access to binding to named controls and [all the other features that XAML bindings bring](binding-from.xaml.md):
```csharp
var textBlock = new TextBlock
{
[!TextBlock.TextProperty] = new Binding("Text") { ElementName = "other" }
};
```

99
docs/spec/binding-from-xaml.md

@ -1,99 +0,0 @@
# Binding from XAML
Binding from XAML works on the whole the same as in other XAML frameworks: you use the `{Binding}`
markup extension. Avalonia does have some extra syntacic niceties however. Here's an overview of
what you can currently do in Avalonia:
## Binding to a property on the DataContext
By default a binding binds to a property on the `DataContext`, e.g.:
```xml
<!-- Binds to the tb.DataContext.Name property -->
<TextBlock Name="tb" Text="{Binding Name}"/>
<!-- Which is the same as ('Path' is optional) -->
<TextBlock Name="tb" Text="{Binding Path=Name}"/>
```
An empty binding binds to DataContext itself
```xml
<!-- Binds to the tb.DataContext property -->
<TextBlock Name="tb" Text="{Binding}"/>
<!-- Which is the same as -->
<TextBlock Name="tb" Text="{Binding .}"/>
```
This usage is identical to WPF/UWP etc.
## Two way bindings and more
You can also specify a binding `Mode`:
```xml
<!-- Bind two-way to the property (although this is actually the default binding mode for
TextBox.Text) so strictly speaking it's unnecessary here) -->
<TextBox Name="tb" Text="{Binding Name, Mode=TwoWay}"/>
```
This usage is identical to WPF/UWP etc.
## Binding to a property on the templated parent
When you're creating a control template and you want to bind to the templated parent you can use:
```xml
<TextBlock Name="tb" Text="{TemplateBinding Caption}"/>
<!-- Which is short for -->
<TextBlock Name="tb" Text="{Binding Caption, RelativeSource={RelativeSource TemplatedParent}}"/>
```
This usage is identical to WPF/UWP etc.
## Binding to a named control
If you want to bind to a property on another (named) control, you can use `ElementName` as in
WPF/UWP:
```xml
<!-- Binds to the Tag property of a control named "other" -->
<TextBlock Text="{Binding Tag, ElementName=other}"/>
```
However Avalonia also introduces a shorthand syntax for this:
```xml
<TextBlock Text="{Binding #other.Tag}"/>
```
## Negating bindings
You can also negate the value of a binding using the `!` operator:
```xml
<TextBox IsEnabled="{Binding !HasErrors}"/>
```
Here, the `TextBox` will only be enabled when the view model signals that it has no errors. Behind
the scenes, Avalonia tries to convert the incoming value to a boolean, and if it can be converted
it negates the value. If the incoming value cannot be converted to a boolean then no value will be
pushed to the binding target.
This syntax is specific to Avalonia.
## Binding to tasks and observables
You can subscribe to the result of a task or an observable by using the `^` stream binding operator.
```xml
<!-- If DataContext.Name is an IObservable<string> then this will bind to the length of each
string produced by the observable as each value is produced -->
<TextBlock Text="{Binding Name^.Length}"/>
```
This syntax is specific to Avalonia.
*Note: the stream operator is actually extensible, see
[here](https://github.com/AvaloniaUI/Avalonia/blob/master/src/Markup/Avalonia.Markup/Data/Plugins/IStreamPlugin.cs)
for the interface to implement and [here](https://github.com/AvaloniaUI/Avalonia/blob/master/src/Markup/Avalonia.Markup/Data/ExpressionObserver.cs#L47)
for the registration.*

199
docs/spec/defining-properties.md

@ -1,199 +0,0 @@
# Defining Properties
If you are creating a control, you will want to define properties on your
control. The process in Avalonia is broadly similar to other XAML languages
with a few differences - the main one being that Perpsex's equivalent of
`DependencyProperty` is called `StyledProperty`.
## Registering Styled Properties
A styled property is analogous to a `DependencyProperty` in other XAML
frameworks.
You register a styled property by calling `AvaloniaProperty.Register` and
storing the result in a `static readonly` field. You then create a standard C#
property to access it.
Here's how the `Border` control defines its `Background` property:
```c#
public static readonly StyledProperty<Brush> BackgroundProperty =
AvaloniaProperty.Register<Border, Brush>(nameof(Background));
public Brush Background
{
get { return GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
```
The `AvaloniaProperty.Register` method also accepts a number of other parameters:
- `defaultValue`: This gives the property a default value. Be sure to only pass
value types and immutable types here as passing a reference type will cause the
same object to be used on all instances on which the property is registered.
- `inherits`: Specified that the property's default value should come from
the parent control.
- `defaultBindingMode`: The default binding mode for the property. Can be set to
`OneWay`, `TwoWay`, `OneTime` or `OneWayToSource`.
- `validate`: A validation/coercion function of type
`Func<TOwner, TValue, TValue>`. The function accepts the instance of the class
on which the property is being set and the value and returns the coerced value
or throws an exception for an invalid value.
## Using a StyledProperty on Another Class
Sometimes the property you want to add to your control already exists on another
control, `Background` being a good example. To register a property defined on
another control, you call `StyledProperty.AddOwner`:
```c#
public static readonly StyledProperty<Brush> BackgroundProperty =
Border.BackgroundProperty.AddOwner<Panel>();
public Brush Background
{
get { return GetValue(BackgroundProperty); }
set { SetValue(BackgroundProperty, value); }
}
```
*Note: Unlike WPF, a property must be registered on a class otherwise it cannot
be set on an object of that class.*
## Attached Properties
Attached properties are defined almost identically to styled properties except
that they are registered using the `RegisterAttached` method and their accessors
are defined as static methods.
Here's how `Grid` defines its `Grid.Column` attached property:
```c#
public static readonly AttachedProperty<int> ColumnProperty =
AvaloniaProperty.RegisterAttached<Grid, Control, int>("Column");
public static int GetColumn(Control element)
{
return element.GetValue(ColumnProperty);
}
public static void SetColumn(Control element, int value)
{
element.SetValue(ColumnProperty, value);
}
```
## Readonly AvaloniaProperties
To create a readonly property you use the `AvaloniaProperty.RegisterDirect`
method. Here is how `Visual` registers the readonly `Bounds` property:
```c#
public static readonly DirectProperty<Visual, Rect> BoundsProperty =
AvaloniaProperty.RegisterDirect<Visual, Rect>(
nameof(Bounds),
o => o.Bounds);
private Rect _bounds;
public Rect Bounds
{
get { return _bounds; }
private set { SetAndRaise(BoundsProperty, ref _bounds, value); }
}
```
As can be seen, readonly properties are stored as a field on the object. When
registering the property, a getter is passed which is used to access the
property value through `GetValue` and then `SetAndRaise` is used to notify
listeners to changes to the property.
## Direct AvaloniaProperties
As its name suggests, `RegisterDirect` isn't just used for registering readonly
properties. You can also pass a *setter* to `RegisterDirect` to expose a
standard C# property as a Avalonia property.
A `StyledProperty` which is registered using `AvaloniaProperty.Register`
maintains a prioritized list of values and bindings that allow styles to work.
However, this is overkill for many properties, such as `ItemsControl.Items` -
this will never be styled and the overhead involved with styled properties is
unnecessary.
Here is how `ItemsControl.Items` is registered:
```c#
public static readonly DirectProperty<ItemsControl, IEnumerable> ItemsProperty =
AvaloniaProperty.RegisterDirect<ItemsControl, IEnumerable>(
nameof(Items),
o => o.Items,
(o, v) => o.Items = v);
private IEnumerable _items = new AvaloniaList<object>();
public IEnumerable Items
{
get { return _items; }
set { SetAndRaise(ItemsProperty, ref _items, value); }
}
```
Direct properties are a lightweight version of styled properties that support
the following:
- AvaloniaObject.GetValue
- AvaloniaObject.SetValue for non-readonly properties
- PropertyChanged
- Binding (only with LocalValue priority)
- GetObservable
- AddOwner
- Metadata
They don't support the following:
- Validation/Coercion (although this could be done in the property setter)
- Overriding default values.
- Inherited values
## Using a DirectProperty on Another Class
In the same way that you can call `AddOwner` on a styled property, you can also
add an owner to a direct property. Because direct properties reference fields
on the control, you must also add a field for the property:
```c#
public static readonly DirectProperty<MyControl, IEnumerable> ItemsProperty =
ItemsControl.ItemsProperty.AddOwner<MyControl>(
o => o.Items,
(o, v) => o.Items = v);
private IEnumerable _items = new AvaloniaList<object>();
public IEnumerable Items
{
get { return _items; }
set { SetAndRaise(ItemsProperty, ref _items, value); }
}
```
## When to use a Direct vs a Styled Property
Direct properties have advantages and disadvantages:
Pros:
- No additional object is allocated per-instance for the property
- Property getter is a standard C# property getter
- Property setter is is a standard C# property setter that raises an event.
Cons:
- Cannot inherit value from parent control
- Cannot take advantage of Avalonia's styling system
- Property value is a field and as such is allocated whether the property is
set on the object or not
So use direct properties when you have the following requirements:
- Property will not need to be styled
- Property will usually or always have a value

54
docs/spec/logging.md

@ -1,54 +0,0 @@
# Avalonia Logging
Avalonia uses [Serilog](https://github.com/serilog/serilog) for logging via
the Avalonia.Logging.Serilog assembly.
The following method should be present in your App.xaml.cs file:
```C#
private void InitializeLogging()
{
#if DEBUG
SerilogLogger.Initialize(new LoggerConfiguration()
.MinimumLevel.Warning()
.WriteTo.Trace(outputTemplate: "{Area}: {Message}")
.CreateLogger());
#endif
}
```
By default, this logging setup will write log messages with a severity of
`Warning` or higher to `System.Diagnostics.Trace`. See the [Serilog
documentation](https://github.com/serilog/serilog/wiki/Configuration-Basics)
for more information on the options here.
## Areas
Each Avalonia log message has an "Area" that can be used to filter the log to
include only the type of events that you are interested in. These are currently:
- Property
- Binding
- Visual
- Layout
- Control
To limit the log output to a specific area you can add a filter; for example
to enable verbose logging but only about layout:
```C#
SerilogLogger.Initialize(new LoggerConfiguration()
.Filter.ByIncludingOnly(Matching.WithProperty("Area", LogArea.Layout))
.MinimumLevel.Verbose()
.WriteTo.Trace(outputTemplate: "{Area}: {Message}")
.CreateLogger());
```
## Removing Serilog
If you don't want a dependency on Serilog in your application, simply remove
the reference to Avalonia.Logging.Serilog and the code that initializes it. If
you do however still want some kinda of logging, there are two steps:
- Implement `Avalonia.Logging.ILogSink`
- Assign your implementation to `Logger.Sink`

111
docs/spec/styles.md

@ -1,111 +0,0 @@
# Styling in Avalonia
The main difference between Avalonia and existing XAML toolkits such as WPF and
UWP is in styling. Styling in Avalonia uses a CSS-like system that aims to be
more powerful and flexible than existing XAML styling systems. For convenience
for the rest of this document we'll refer to existing XAML toolkit's styling as
"WPF styling" as that's where it originated.
## Basics
- Styles are defined on the `Control.Styles` collection (as opposed to in
`ResourceDictionaries` in WPF).
- Styles have a `Selector` and a collection of `Setter`s
- Selector works like a CSS selector.
- Setters function like WPF's setters.
- Styles are applied to a control and all its descendants, depending on whether
the selector matches.
## Simple example
Make all `Button`s in a `StackPanel` have a blue `Background`:
```xaml
<StackPanel>
<StackPanel.Styles>
<Style Selector="Button">
<Setter Property="Button.Background" Value="Blue"/>
</Style>
</StackPanel.Styles>
<Button>I will have a blue background.</Button>
</StackPanel>
```
This is very similar to WPF, except `TargetType` is replaced by `Selector`.
_Note that currently (as of Alpha 2) you **always** need to specify the fully
qualified property name (i.e. `Button.Background` instead of simply
`Background`). This restriction will be lifted in future._
## Style Classes
As in CSS, controls can be given *style classes* which can be used in selectors:
```xaml
<StackPanel>
<StackPanel.Styles>
<Style Selector="Button.blue">
<Setter Property="Button.Background" Value="Blue"/>
</Style>
</StackPanel.Styles>
<Button Classes="blue">I will have a blue background.</Button>
<Button>I will not.</Button>
</StackPanel>
```
Each control can be given 0 or more style classes. This is different to WPF
where only a single style can be applied to a control: in Avalonia any number
of separate styles can be applied to a control. If more than one style affects
a particular property, the style closest to the control will take precedence.
Style classes can also be manipulated in code using the `Classes` collection:
```csharp
control.Classes.Add("blue");
control.Classes.Remove("red");
```
## Pseudoclasses
Also as in CSS, controls can have pseudoclasses; these are classes that are
defined by the control itself rather than by the user. Pseudoclasses start
with a `:` character.
One example of a pseudoclass is the `:pointerover`
pseudoclass (`:hover` in CSS - we may change to that in future).
Pseudoclasses provide the functionality of `Triggers` in WPF and
`VisualStateManager` in UWP:
```xaml
<StackPanel>
<StackPanel.Styles>
<Style Selector="Button:pointerover">
<Setter Property="Button.Foreground" Value="Red"/>
</Style>
</StackPanel.Styles>
<Button>I will have red text when hovered.</Button>
</StackPanel>
```
Other pseudoclasses include `:focus`, `:disabled`, `:pressed` for buttons,
`:checked` for checkboxes etc.
## Named Controls
Named controls can be selected using `#` as in CSS, e.g. `Button#Name`.
## Children
As with CSS, you can select children and descendants:
- `StackPanel > Button#Foo` selects a `Button` named `"Foo"` that is the child
of a `StackPanel`.
- `StackPanel Button.foo` selects all `Button`s with the `foo` class that are
descendants of a `StackPanel`.
## Templates
You can select controls in the template of a lookless control by using the
`/template/` selector, so `Button /template/ Border#outline` selects `Border`
controls named `"outline"` in the template of a `Button`.

14
docs/spec/toc.yml

@ -1,14 +0,0 @@
- name: Avalonia Architecture
href: architecture.md
- name: Styling in Avalonia
href: styles.md
- name: Defining Properties
href: defining-properties.md
- name: Working with Properties
href: working-with-properties.md
- name: Logging
href: logging.md
- name: Binding from XAML
href: binding-from-xaml.md
- name: Binding from Code
href: binding-from-code.md

102
docs/spec/working-with-properties.md

@ -1,102 +0,0 @@
# Working with Properties
Avalonia controls expose their properties as standard CLR properties, so for
reading and writing values there's no surprises:
```c#
// Create a TextBlock and set its Text property.
var textBlock = new TextBlock();
textBlock.Text = "Hello World!";
```
However there's a lot more you can do with properties such as subscribing to
changes on the property, and binding.
# Subscribing to Changes to a Property
You can subscribe to changes on a property by calling the `GetObservable`
method. This returns an `IObservable<T>` which can be used to listen for changes
to the property:
```c#
var textBlock = new TextBlock();
var text = textBlock.GetObservable(TextBlock.TextProperty);
```
Each property that can be subscribed to has a static readonly field called
`[PropertyName]Property` which is passed to `GetObservable` in order to
subscribe to the property's changes.
`IObservable` (part of Reactive Extensions, or rx for short) is out of scope
for this guide, but here's an example which uses the returned observable to
print a message with the changing property values to the console:
```c#
var textBlock = new TextBlock();
var text = textBlock.GetObservable(TextBlock.TextProperty);
text.Subscribe(value => Console.WriteLine(value + " Changed"));
```
When the returned observable is subscribed, it will return the current value
of the property immediately and then push a new value each time the property
changes. If you don't want the current value, you can use the rx `Skip`
operator:
```c#
var text = textBlock.GetObservable(TextBlock.TextProperty).Skip(1);
```
# Binding a property
Observables don't just go one way! You can also use them to bind properties.
For example here we create two `TextBlock`s and bind the second's `Text`
property to the first:
```c#
var textBlock1 = new TextBlock();
var textBlock2 = new TextBlock();
// Get an observable for the first text block's Text property.
var source = textBlock1.GetObservable(TextBlock.TextProperty);
// And bind it to the second.
textBlock2.Bind(TextBlock.TextProperty, source);
// Changes to the first TextBlock's Text property will now be propagated
// to the second.
textBlock1.Text = "Goodbye Cruel World";
// Prints "Goodbye Cruel World"
Console.WriteLine(textBlock2.Text);
```
To read more about creating bindings from code, see [Binding from Code](binding-from-code.md).
# Subscribing to a Property on Any Object
The `GetObservable` method returns an observable that tracks changes to a
property on a single instance. However, if you're writing a control you may
want to implement an `OnPropertyChanged` method. In WPF this is done by passing
a static `PropertyChangedCallback` to the `DependencyProperty` registration
method, but in Avalonia it's slightly different (and hopefully easier!)
The field which defines the property is derived from `AvaloniaProperty` and this
has a `Changed` observable which is fired every time the property changes on
*any* object. In addition there is an `AddClassHandler` extension method which
can automatically route the event to a method on your control.
For example if you want to listen to changes to your control's `Foo` property
you'd do it like this:
```c#
static MyControl()
{
FooProperty.Changed.AddClassHandler<MyControl>(x => x.FooChanged);
}
private void FooChanged(AvaloniaPropertyChangedEventArgs e)
{
// The 'e' parameter describes what's changed.
}
```

13
docs/template/partials/footer.tmpl.partial

@ -1,13 +0,0 @@
{{!Copyright (c) Microsoft. All rights reserved. Licensed under the MIT license. See LICENSE file in the project root for full license information.}}
<footer>
<div class="grad-bottom"></div>
<div class="footer">
<div class="container">
<span class="pull-right">
<a href="#top">Back to top</a>
</span>
<span>Copyright © 2016 The Avalonia Project<br>Generated by <strong>DocFX</strong></span>
</div>
</div>
</footer>

10
docs/toc.yml

@ -1,10 +0,0 @@
- name: Home
href: index.md
- name: Getting Started
href: tutorial/
- name: Guidelines
href: guidelines/
- name: Specifications
href: spec/
- name: API Documentation
href: api/

172
docs/tutorial/from-wpf.md

@ -1,172 +0,0 @@
# Avalonia for WPF Developers
Avalonia is in general very similar to WPF, but you will find differences. Here
are the most common:
## Styling
The most obvious difference from other XAML frameworks is that Avalonia uses a
[CSS-like styling system](../spec/styles.md). Styles aren't stored in a
`Resources` collection as in WPF, they are stored in a separate `Styles`
collection:
<UserControl>
<UserControl.Styles>
<!-- Make TextBlocks with the h1 style class have a font size of 24 points -->
<Style Selector="TextBlock.h1">
<Setter Property="FontSize" Value="24"/>
</Style>
</UserControl.Styles>
<TextBlock Classes="h1">Header</TextBlock>
<UserControl>
## DataTemplates
As styles aren't stored in `Resources`, neither are `DataTemplates` ([in fact
there is no `Resources` collection](#resources)). Instead, `DataTemplates` are
placed in a `DataTemplates` collection on each control (and on `Application`):
<UserControl xmlns:viewmodels="clr-namespace:MyApp.ViewModels;assembly=MyApp">
<UserControl.DataTemplates>
<DataTemplate DataType="viewmodels:FooViewModel">
<Border Background="Red" CornerRadius="8">
<TextBox Text="{Binding Name}"/>
</Border>
</DataTemplate>
</UserControl.Styles>
<!-- 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 -->
<ContentControl Content="{Binding Foo}"/>
<UserControl>
Data templates in Avalonia can also target interfaces and derived classes (which
cannot be done in WPF) and so the order of `DataTemplate`s can be important:
`DataTemplate`s within the same collection are evaluated in declaration order
so you need to place them from most-specific to least-specific as you would in
code.
## HierachicalDataTemplate
WPF's `HierarchicalDataTemplate` is called `TreeDataTemplate` in Avalonia (as the
former is difficult to type!). The two are almost entirely equivalent except
that the `ItemTemplate` property is not present in Avalonia.
## UIElement, FrameworkElement and Control
WPF's `UIElement` and `FrameworkElement` are non-templated control base classes,
which roughly equate to the Avalonia `Control` class. WPF's `Control` class on
the other hand is a templated control - Avalonia's equivalent of this is
`TemplatedControl`.
So to recap:
- `UIElement`: `Control`
- `FrameworkElement`: `Control`
- `Control`: `TemplatedControl`
## DependencyProperty
The Avalonia equivalent of `DependencyProperty` is `StyledProperty`, however
Avalonia [has a richer property system than WPF](../spec/defining-properties.md),
and includes `DirectProperty` for turning standard CLR properties into Avalonia
properties. The common base class of `StyledProperty` and `DirectProperty`
is `AvaloniaProperty`.
# Resources
There is no `Resources` collection on controls in Avalonia, however `Style`s
do have a `Resources` collection for style-related resources. These can be
referred to using the `{StyleResource}` markup extension both inside and outside
styles.
For non-style-related resources, we suggest defining them in code and referring
to them in markup using the `{Static}` markup extension. To read more about the reasoning for this,
see [this issue comment](https://github.com/AvaloniaUI/Avalonia/issues/462#issuecomment-191849723).
## Grid
Column and row definitions can be specified in Avalonia using strings, avoiding
the clunky syntax in WPF:
<Grid ColumnDefinitions="Auto,*,32" RowDefinitions="*,Auto">
A common use of `Grid` in WPF is to stack two controls on top of each other.
For this purpose in Avalonia you can just use a `Panel` which is more lightweight
than `Grid`.
We don't yet support `SharedSizeScope` in `Grid`.
## ItemsControl
In WPF, `ItemsControl` and derived classes such as `ListBox` have two separate
items properties: `Items` and `ItemsSource`. Avalonia however just has a single
one: `Items`.
## Tunnelling Events
Avalonia has tunnelling events (unlike UWP!) but they're not exposed via
separate `Preview` CLR event handlers. To subscribe to a tunnelling event you
must call `AddHandler` with `RoutingStrategies.Tunnel`:
```
target.AddHandler(InputElement.KeyDownEvent, OnPreviewKeyDown, RoutingStrategies.Tunnel);
void OnPreviewKeyDown(object sender, KeyEventArgs e)
{
// Handler code
}
```
## Class Handlers
In WPF, class handlers for events can be added by calling
[EventManager.RegisterClassHandler](https://msdn.microsoft.com/en-us/library/ms597875.aspx).
An example of registering a class handler in WPF might be:
static MyControl()
{
EventManager.RegisterClassHandler(typeof(MyControl), MyEvent, HandleMyEvent));
}
private static void HandleMyEvent(object sender, RoutedEventArgs e)
{
}
The equivalent of this in Avalonia would be:
static MyControl()
{
MyEvent.AddClassHandler<MyControl>(x => x.HandleMyEvent);
}
private void HandleMyEvent(object sender, RoutedEventArgs e)
{
}
Notice that in WPF you have to add the class handler as a static method, whereas
in Avalonia the class handler is not static: the notification is automatically
directed to the correct instance.
## PropertyChangedCallback
Listening to changes on DependencyProperties in WPF can be complex. When you
register a `DependencyProperty` you can supply a static `PropertyChangedCallback`
but if you want to listen to changes from elsewhere [things can get complicated
and error-prone](http://stackoverflow.com/questions/23682232).
In Avalonia, there is no `PropertyChangedCallback` at the time of registration,
instead a class listener is [added to the control's static constructor in much
the same way that event class listeners are added](../spec/working-with-properties.md#subscribing-to-a-property-on-any-object).
## 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:
In WPF:
![WPF](https://files.gitter.im/AvaloniaUI/Avalonia/cDrM/image.png)
In Avalonia:
![Avalonia](https://files.gitter.im/AvaloniaUI/Avalonia/KGk7/image.png)
In AvaloniaUI, to get the same scale transform we should indicate that the RenderTransformOrigin is the TopLeft part of the Visual.

10
docs/tutorial/gettingstarted.md

@ -1,10 +0,0 @@
# Getting Started
## Windows
![](images/add-dialogs.png)
The easiest way to try out Avalonia is to install the [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio).
This will add a Avalonia project template and a Window template to the standard Visual Studo “Add”
dialog (yes, icons still to come :) ):

BIN
docs/tutorial/images/add-dialogs.png

Binary file not shown.

Before

Width:  |  Height:  |  Size: 45 KiB

86
docs/tutorial/nuget.md

@ -1,86 +0,0 @@
# Avalonia NuGet Packages
Avalonia is divided into several `NuGet` packages.
* The `Avalonia` package contains core portable class libraries.
* The `Dekstop` and `Mobile` packages contain platform specific windowing and rendering back-ends.
* The `Avalonia.Desktop` package is intended to be used by the end users targeting multiple desktop platforms (`Windows`, `Linux` and `OSX`).
* The `Avalonia.iOS` and `Avalonia.Android` packages are intended to be used by the end users targeting specific mobile platforms.
* The `Avalonia.Mobile` package is intended to be used by the end users targeting multiple mobile platforms (`Android` and `iOS`).
## Core
* Avalonia (.nupkg)
- Avalonia.Animation (.dll)
- Avalonia.Base (.dll)
- Avalonia.Controls (.dll)
- Avalonia.DesignerSupport (.dll)
- Avalonia.Diagnostics (.dll)
- Avalonia.Input (.dll)
- Avalonia.Interactivity (.dll)
- Avalonia.Layout (.dll)
- Avalonia.Logging.Serilog (.dll)
- Avalonia.Visuals (.dll)
- Avalonia.Styling (.dll)
- Avalonia.ReactiveUI (.dll)
- Avalonia.Themes.Default (.dll)
- Avalonia.Markup (.dll)
- Avalonia.Markup.Xaml (.dll)
- Serilog (.nupkg)
- Splat (.nupkg)
- Sprache (.nupkg)
- System.Reactive (.nupkg)
* Avalonia.HtmlRenderer (.nupkg)
- Avalonia (.nupkg)
## Desktop
* Avalonia.Win32 (.nupkg)
- Avalonia.Win32 (.dll)
- Avalonia (.nupkg)
* Avalonia.Direct2D1 (.nupkg)
- Avalonia.Direct2D1 (.dll)
- Avalonia (.nupkg)
- SharpDX (.nupkg)
- SharpDX.Direct2D1 (.nupkg)
- SharpDX.DXGI (.nupkg)
* Avalonia.Gtk (.nupkg)
- Avalonia.Gtk (.dll)
- Avalonia (.nupkg)
* Avalonia.Cairo (.nupkg)
- Avalonia.Cairo (.dll)
- Avalonia (.nupkg)
* Avalonia.Skia.Desktop (.nupkg)
- Avalonia.Skia.Desktop (.dll)
- Avalonia (.nupkg)
- SkiaSharp (.nupkg)
* Avalonia.Desktop (.nupkg)
- Avalonia.Win32 (.nupkg)
- Avalonia.Direct2D1 (.nupkg)
- Avalonia.Gtk (.nupkg)
- Avalonia.Cairo (.nupkg)
- Avalonia.Skia.Desktop (.nupkg)
## Mobile
* Avalonia.Android (.nupkg)
- Avalonia.Android (.dll)
- Avalonia.Skia.Android (.dll)
- Avalonia (.nupkg)
- SkiaSharp (.nupkg)
* Avalonia.iOS (.nupkg)
- Avalonia.iOS (.dll)
- Avalonia.Skia.iOS (.dll)
- Avalonia (.nupkg)
- SkiaSharp (.nupkg)
* Avalonia.Mobile (.nupkg)
- Avalonia.Android (.nupkg)
- Avalonia.iOS (.nupkg)

6
docs/tutorial/toc.yml

@ -1,6 +0,0 @@
- name: Getting Started
href: gettingstarted.md
- name: Avalonia NuGet Packages
href: nuget.md
- name: Avalonia for WPF Developers
href: from-wpf.md

338
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 =>
{
@ -72,25 +107,32 @@ public class Packages
context.Information("Setting NuGet package dependencies versions:");
var SerilogVersion = packageVersions["Serilog"].FirstOrDefault().Item1;
var SplatVersion = packageVersions["Splat"].FirstOrDefault().Item1;
var SerilogSinksDebugVersion = packageVersions["Serilog.Sinks.Debug"].FirstOrDefault().Item1;
var SerilogSinksTraceVersion = packageVersions["Serilog.Sinks.Trace"].FirstOrDefault().Item1;
var SpracheVersion = packageVersions["Sprache"].FirstOrDefault().Item1;
var SystemReactiveVersion = packageVersions["System.Reactive"].FirstOrDefault().Item1;
var ReactiveUIVersion = packageVersions["reactiveui"].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;
var SystemComponentModelAnnotationsVersion = packageVersions["System.ComponentModel.Annotations"].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: reactiveui, version: {0}", ReactiveUIVersion);
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")
@ -114,44 +156,33 @@ public class Packages
var coreLibraries = new string[][]
{
new [] { "./src/", "Avalonia.Animation", ".dll" },
new [] { "./src/", "Avalonia.Animation", ".xml" },
new [] { "./src/", "Avalonia.Base", ".dll" },
new [] { "./src/", "Avalonia.Base", ".xml" },
new [] { "./src/", "Avalonia.Controls", ".dll" },
new [] { "./src/", "Avalonia.Controls", ".xml" },
new [] { "./src/", "Avalonia.DesignerSupport", ".dll" },
new [] { "./src/", "Avalonia.DesignerSupport", ".xml" },
new [] { "./src/", "Avalonia.Diagnostics", ".dll" },
new [] { "./src/", "Avalonia.Diagnostics", ".xml" },
new [] { "./src/", "Avalonia.Input", ".dll" },
new [] { "./src/", "Avalonia.Input", ".xml" },
new [] { "./src/", "Avalonia.Interactivity", ".dll" },
new [] { "./src/", "Avalonia.Interactivity", ".xml" },
new [] { "./src/", "Avalonia.Layout", ".dll" },
new [] { "./src/", "Avalonia.Layout", ".xml" },
new [] { "./src/", "Avalonia.Logging.Serilog", ".dll" },
new [] { "./src/", "Avalonia.Logging.Serilog", ".xml" },
new [] { "./src/", "Avalonia.Visuals", ".dll" },
new [] { "./src/", "Avalonia.Visuals", ".xml" },
new [] { "./src/", "Avalonia.Styling", ".dll" },
new [] { "./src/", "Avalonia.Styling", ".xml" },
new [] { "./src/", "Avalonia.ReactiveUI", ".dll" },
new [] { "./src/", "Avalonia.Themes.Default", ".dll" },
new [] { "./src/", "Avalonia.Themes.Default", ".xml" },
new [] { "./src/Markup/", "Avalonia.Markup", ".dll" },
new [] { "./src/Markup/", "Avalonia.Markup", ".xml" },
new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".dll" },
new [] { "./src/Markup/", "Avalonia.Markup.Xaml", ".xml" }
new [] { "./src/", "Avalonia.Animation"},
new [] { "./src/", "Avalonia.Base"},
new [] { "./src/", "Avalonia.Controls"},
new [] { "./src/", "Avalonia.DesignerSupport"},
new [] { "./src/", "Avalonia.Diagnostics"},
new [] { "./src/", "Avalonia.Input"},
new [] { "./src/", "Avalonia.Interactivity"},
new [] { "./src/", "Avalonia.Layout"},
new [] { "./src/", "Avalonia.Logging.Serilog"},
new [] { "./src/", "Avalonia.Visuals"},
new [] { "./src/", "Avalonia.Styling"},
new [] { "./src/", "Avalonia.Themes.Default"},
new [] { "./src/Markup/", "Avalonia.Markup"},
new [] { "./src/Markup/", "Avalonia.Markup.Xaml"},
};
var coreLibrariesFiles = coreLibraries.Select((lib) => {
return (FilePath)context.File(lib[0] + lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard1.1/" + lib[1] + lib[2]);
var extensionsToPack = new [] {".dll", ".xml", ".pdb"};
var coreLibrariesFiles = coreLibraries
.SelectMany(lib => extensionsToPack.Select(ext => new {lib, ext}))
.Select((lib) => {
return (FilePath)context.File(lib.lib[0] + lib.lib[1] + "/bin/" + parameters.DirSuffix + "/netstandard2.0/" + lib.lib[1] + lib.ext);
}).ToList();
var coreLibrariesNuSpecContent = coreLibrariesFiles.Select((file) => {
return new NuSpecContent {
Source = file.FullPath, Target = "lib/netstandard1.1"
Source = file.FullPath, Target = "lib/netstandard2.0"
};
});
@ -163,26 +194,35 @@ 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 => {
var net45RuntimePlatform = extensionsToPack.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"
};
});
var netCoreRuntimePlatformExtensions = new [] {".xml", ".dll"};
var netCoreRuntimePlatform = netCoreRuntimePlatformExtensions.Select(libSuffix => {
var netCoreRuntimePlatform = extensionsToPack.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"
};
});
var toolsContent = new[] {
new NuSpecContent{
Source = ((FilePath)context.File("./src/tools/Avalonia.Designer.HostApp/bin/" + parameters.DirSuffix + "/netcoreapp2.0/Avalonia.Designer.HostApp.dll")).FullPath,
Target = "tools/netcoreapp2.0/previewer"
},
new NuSpecContent{
Source = ((FilePath)context.File("./src/tools/Avalonia.Designer.HostApp.NetFx/bin/" + parameters.DirSuffix + "/Avalonia.Designer.HostApp.exe")).FullPath,
Target = "tools/net461/previewer"
}
};
var nuspecNuGetSettingsCore = new []
{
///////////////////////////////////////////////////////////////////////////////
@ -191,83 +231,88 @@ 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 = "Serilog.Sinks.Debug", Version = SerilogSinksDebugVersion },
new NuSpecDependency() { Id = "Serilog.Sinks.Trace", Version = SerilogSinksTraceVersion },
new NuSpecDependency() { Id = "Sprache", Version = SpracheVersion },
new NuSpecDependency() { Id = "System.Reactive", Version = SystemReactiveVersion },
new NuSpecDependency() { Id = "Avalonia.Remote.Protocol", Version = parameters.Version },
new NuSpecDependency() { Id = "System.ComponentModel.Annotations", Version = SystemComponentModelAnnotationsVersion },
//.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 = "Serilog", TargetFramework = "netcoreapp2.0", Version = SerilogVersion },
new NuSpecDependency() { Id = "Serilog.Sinks.Debug", TargetFramework = "netcoreapp2.0", Version = SerilogSinksDebugVersion },
new NuSpecDependency() { Id = "Serilog.Sinks.Trace", TargetFramework = "netcoreapp2.0", Version = SerilogSinksTraceVersion },
new NuSpecDependency() { Id = "Sprache", TargetFramework = "netcoreapp2.0", Version = SpracheVersion },
new NuSpecDependency() { Id = "System.Reactive", TargetFramework = "netcoreapp2.0", Version = SystemReactiveVersion },
new NuSpecDependency() { Id = "Avalonia.Remote.Protocol", TargetFramework = "netcoreapp2.0", Version = parameters.Version },
}
.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)
.Concat(toolsContent)
.ToList(),
BasePath = context.Directory("./"),
OutputDirectory = parameters.NugetRoot
},
///////////////////////////////////////////////////////////////////////////////
// Avalonia.HtmlRenderer
// Avalonia.ReactiveUI
///////////////////////////////////////////////////////////////////////////////
new NuGetPackSettings()
{
Id = "Avalonia.HtmlRenderer",
Dependencies = new []
Id = "Avalonia.ReactiveUI",
Dependencies = new DependencyBuilder(this)
{
new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
},
new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
}.Deps(new string[] {null}, "reactiveui"),
Files = new []
{
new NuSpecContent { Source = "Avalonia.HtmlRenderer.dll", Target = "lib/netstandard1.1" }
new NuSpecContent { Source = "Avalonia.ReactiveUI.dll", Target = "lib/netstandard2.0" }
},
BasePath = context.Directory("./src/Avalonia.HtmlRenderer/bin/" + parameters.DirSuffix + "/netstandard1.1"),
BasePath = context.Directory("./src/Avalonia.ReactiveUI/bin/" + parameters.DirSuffix + "/netstandard2.0"),
OutputDirectory = parameters.NugetRoot
}
};
var nuspecNuGetSettingsMobile = new []
{
},
///////////////////////////////////////////////////////////////////////////////
// Avalonia.Android
// Avalonia.Remote.Protocol
///////////////////////////////////////////////////////////////////////////////
new NuGetPackSettings()
{
Id = "Avalonia.Android",
Dependencies = new []
{
new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Skia.Android", Version = parameters.Version }
},
Id = "Avalonia.Remote.Protocol",
Files = new []
{
new NuSpecContent { Source = "Avalonia.Android.dll", Target = "lib/MonoAndroid10" }
new NuSpecContent { Source = "Avalonia.Remote.Protocol.dll", Target = "lib/netstandard2.0" }
},
BasePath = context.Directory("./src/Android/Avalonia.Android/bin/" + parameters.DirSuffix),
BasePath = context.Directory("./src/Avalonia.Remote.Protocol/bin/" + parameters.DirSuffix + "/netstandard2.0"),
OutputDirectory = parameters.NugetRoot
},
};
var nuspecNuGetSettingsMobile = new []
{
///////////////////////////////////////////////////////////////////////////////
// Avalonia.Skia.Android
// Avalonia.Android
///////////////////////////////////////////////////////////////////////////////
new NuGetPackSettings()
{
Id = "Avalonia.Skia.Android",
Id = "Avalonia.Android",
Dependencies = new []
{
new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion }
new NuSpecDependency() { Id = "Avalonia.Skia", Version = parameters.Version }
},
Files = new []
{
new NuSpecContent { Source = "Avalonia.Skia.Android.dll", Target = "lib/MonoAndroid10" }
new NuSpecContent { Source = "Avalonia.Android.dll", Target = "lib/MonoAndroid10" }
},
BasePath = context.Directory("./src/Skia/Avalonia.Skia.Android/bin/" + parameters.DirSuffix),
BasePath = context.Directory("./src/Android/Avalonia.Android/bin/" + parameters.DirSuffix),
OutputDirectory = parameters.NugetRoot
},
///////////////////////////////////////////////////////////////////////////////
@ -279,7 +324,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 +332,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
}
};
@ -334,14 +343,13 @@ public class Packages
new NuGetPackSettings()
{
Id = "Avalonia.Win32",
Dependencies = new []
Dependencies = new DependencyBuilder(this)
{
new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
},
}.Deps(new string[]{null}, "System.Drawing.Common"),
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/bin/" + parameters.DirSuffix + "/netstandard2.0/Avalonia.Win32.dll", Target = "lib/netstandard2.0" }
},
BasePath = context.Directory("./src/Windows"),
OutputDirectory = parameters.NugetRoot
@ -362,107 +370,101 @@ 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
},
///////////////////////////////////////////////////////////////////////////////
// Avalonia.Gtk
// Avalonia.Gtk3
///////////////////////////////////////////////////////////////////////////////
new NuGetPackSettings()
{
Id = "Avalonia.Gtk",
Id = "Avalonia.Gtk3",
Dependencies = new []
{
new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
},
Files = new []
{
new NuSpecContent { Source = "Avalonia.Gtk.dll", Target = "lib/net45" }
new NuSpecContent { Source = "Avalonia.Gtk3.dll", Target = "lib/netstandard2.0" }
},
BasePath = context.Directory("./src/Gtk/Avalonia.Gtk/bin/" + parameters.DirSuffix),
BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard2.0"),
OutputDirectory = parameters.NugetRoot
},
///////////////////////////////////////////////////////////////////////////////
// Avalonia.Gtk3
// Avalonia.Skia
///////////////////////////////////////////////////////////////////////////////
new NuGetPackSettings()
{
Id = "Avalonia.Gtk3",
Id = "Avalonia.Skia",
Dependencies = new []
{
new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version },
new NuSpecDependency() { Id = "SkiaSharp", Version = SkiaSharpVersion },
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.Gtk3.dll", Target = "lib/netstandard1.1" }
new NuSpecContent { Source = "Avalonia.Skia.dll", Target = "lib/netstandard2.0" }
},
BasePath = context.Directory("./src/Gtk/Avalonia.Gtk3/bin/" + parameters.DirSuffix + "/netstandard1.1"),
BasePath = context.Directory("./src/Skia/Avalonia.Skia/bin/" + parameters.DirSuffix + "/netstandard2.0"),
OutputDirectory = parameters.NugetRoot
},
///////////////////////////////////////////////////////////////////////////////
// Avalonia.Cairo
///////////////////////////////////////////////////////////////////////////////
new NuGetPackSettings()
{
Id = "Avalonia.Cairo",
Dependencies = new []
Id = "Avalonia.MonoMac",
Dependencies = new DependencyBuilder(this)
{
new NuSpecDependency() { Id = "Avalonia", Version = parameters.Version }
},
}.Dep("MonoMac.NetStandard").ToArray(),
Files = new []
{
new NuSpecContent { Source = "Avalonia.Cairo.dll", Target = "lib/net45" }
new NuSpecContent { Source = "netstandard2.0/Avalonia.MonoMac.dll", Target = "lib/netstandard2.0" },
},
BasePath = context.Directory("./src/Gtk/Avalonia.Cairo/bin/" + parameters.DirSuffix),
BasePath = context.Directory("./src/OSX/Avalonia.MonoMac/bin/" + parameters.DirSuffix),
OutputDirectory = parameters.NugetRoot
},
///////////////////////////////////////////////////////////////////////////////
// Avalonia.Skia.Desktop
// Avalonia.Desktop
///////////////////////////////////////////////////////////////////////////////
new NuGetPackSettings()
{
Id = "Avalonia.Skia.Desktop",
Id = "Avalonia.Desktop",
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.Direct2D1", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Win32", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Skia", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Gtk3", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.MonoMac", Version = parameters.Version }
},
Files = new []
Files = new NuSpecContent[]
{
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 = "licence.md", Target = "" }
},
BasePath = context.Directory("./src/Skia/"),
BasePath = context.Directory("./"),
OutputDirectory = parameters.NugetRoot
},
///////////////////////////////////////////////////////////////////////////////
// Avalonia.Desktop
///////////////////////////////////////////////////////////////////////////////
new NuGetPackSettings()
{
Id = "Avalonia.Desktop",
Id = "Avalonia.Win32.Interoperability",
Dependencies = new []
{
//Full .NET
new NuSpecDependency() { Id = "Avalonia.Direct2D1", TargetFramework="net45", Version = parameters.Version },
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.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", Version = parameters.Version },
new NuSpecDependency() { Id = "Avalonia.Direct2D1", Version = parameters.Version },
new NuSpecDependency() { Id = "SharpDX.Direct3D9", Version = SharpDXDirect3D9Version },
},
Files = new NuSpecContent[]
Files = new []
{
new NuSpecContent { Source = "licence.md", Target = "" }
new NuSpecContent { Source = "Avalonia.Win32.Interop/bin/" + parameters.DirSuffix + "/Avalonia.Win32.Interop.dll", Target = "lib/net45" }
},
BasePath = context.Directory("./"),
BasePath = context.Directory("./src/Windows"),
OutputDirectory = parameters.NugetRoot
},
///////////////////////////////////////////////////////////////////////////////
@ -474,11 +476,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

42
parameters.cake

@ -1,6 +1,5 @@
public class Parameters
{
public string Target { get; private set; }
public string Platform { get; private set; }
public string Configuration { get; private set; }
public bool SkipTests { get; private set; }
@ -30,9 +29,7 @@ public class Parameters
public DirectoryPath NugetRoot { get; private set; }
public DirectoryPath ZipRoot { get; private set; }
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; }
@ -45,7 +42,6 @@ public class Parameters
var buildSystem = context.BuildSystem();
// ARGUMENTS
Target = context.Argument("target", "Default");
Platform = context.Argument("platform", "Any CPU");
Configuration = context.Argument("configuration", "Release");
SkipTests = context.HasArgument("skip-tests");
@ -98,7 +94,7 @@ public class Parameters
else
{
// Use AssemblyVersion with Build as version
Version += "-build" + context.EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-alpha";
Version += "-build" + context.EnvironmentVariable("APPVEYOR_BUILD_NUMBER") + "-beta";
}
}
@ -107,45 +103,15 @@ public class Parameters
NugetRoot = ArtifactsDir.Combine("nuget");
ZipRoot = ArtifactsDir.Combine("zip");
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);
ZipSourceControlCatalogDesktopDirs = (DirectoryPath)context.Directory("./samples/ControlCatalog.Desktop/bin/" + DirSuffix + "/net461");
ZipTargetControlCatalogDesktopDirs = ZipRoot.CombineWithFilePath("ControlCatalog.Desktop-" + FileZipSuffix);
}
}

92
readme.md

@ -1,70 +1,80 @@
# Avalonia
<img src='https://avatars2.githubusercontent.com/u/14075148?s=200&v=4' width='100' />
# Avalonia
| Gitter Chat | Windows Build Status | Linux/Mac Build Status | Code Coverage |
| Gitter Chat | Windows Build Status | Linux/Mac Build Status | Open Collective |
|---|---|---|---|
| [![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](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) | [![Backers on Open Collective](https://opencollective.com/Avalonia/backers/badge.svg)](#backers) [![Sponsors on Open Collective](https://opencollective.com/Avalonia/sponsors/badge.svg)](#sponsors) |
A multi-platform .NET UI framework. It can run on Windows, Linux, Mac OS X, iOS and Android.
## About
![](docs/images/screen.png)
Avalonia is a WPF-inspired cross-platform XAML-based UI framework providing a flexible styling system and supporting a wide range of OSs: Windows (.NET Framework, .NET Core), Linux (GTK), MacOS, Android and iOS.
Desktop platforms:
**Avalonia is currently in beta** which means that the framework is generally usable for writing applications, but there may be some bugs and breaking changes as we continue development.
<a href='https://www.youtube.com/watch?t=28&v=c_AB_XSILp0' target='_blank'>![](docs/images/avalonia-video.png)<a/>
| Control catalog | Desktop platforms | Mobile platforms |
|---|---|---|
| <a href='https://youtu.be/wHcB3sGLVYg'><img width='300' src='http://avaloniaui.net/images/screen.png'></a> | <a href='https://www.youtube.com/watch?t=28&v=c_AB_XSILp0' target='_blank'><img width='300' src='http://avaloniaui.net/images/avalonia-video.png'></a> | <a href='https://www.youtube.com/watch?v=NJ9-hnmUbBM' target='_blank'><img width='300' src='https://i.ytimg.com/vi/NJ9-hnmUbBM/hqdefault.jpg'></a> |
Mobile platforms:
## Getting Started
<a href='https://www.youtube.com/watch?v=NJ9-hnmUbBM' target='_blank'>![](https://i.ytimg.com/vi/NJ9-hnmUbBM/hqdefault.jpg)<a/>
Avalonia [Visual Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio) contains project and control templates that will help you get started. After installing it, open "New Project" dialog in Visual Studio, choose "Avalonia" in "Visual C#" section, select "Avalonia .NET Core Application" and press OK (<a href="http://avaloniaui.net/docs/quickstart/images/new-project-dialog.png">screenshot</a>). Now you can write code and markup that will work on multiple platforms!
## NuGet
Avalonia is delivered via <b>NuGet</b> package manager. You can find the packages here: ([stable(ish)](https://www.nuget.org/packages/Avalonia/), [nightly](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed))
Avalonia is delivered as a NuGet package.
You can find the packages here: ([stable(ish)](https://www.nuget.org/packages/Avalonia/), [nightly](https://github.com/AvaloniaUI/Avalonia/wiki/Using-nightly-build-feed))
You can install the package like this:
`Install-Package Avalonia -Pre`
Use these commands in Package Manager console to install Avalonia manually:
```
Install-Package Avalonia
Install-Package Avalonia.Desktop
```
## Bleeding Edge Builds
Try out the latest build of Avalonia available for download here:
https://ci.appveyor.com/project/AvaloniaUI/Avalonia/branch/master/artifacts
Try out the ControlCatalog to give it a quick demo.
## Documentation
## Background
As mentioned above, Avalonia is still in beta and as such there's not much documentation yet. You can take a look at the [getting started page](http://avaloniaui.net/docs/quickstart/) for an overview of how to get started but probably the best thing to do for now is to already know a little bit about WPF/Silverlight/UWP/XAML and ask questions in our [Gitter room](https://gitter.im/AvaloniaUI/Avalonia).
Avalonia is a multi-platform windowing toolkit - somewhat like WPF - that is intended to be multi-
platform. It supports XAML, lookless controls and a flexible styling system, and runs on Windows
using Direct2D and other operating systems using Gtk & Cairo.
There's also a high-level [architecture document](http://avaloniaui.net/architecture/project-structure) that is currently a little bit out of date, and I've also started writing blog posts on Avalonia at http://grokys.github.io/.
## Current Status
Contributions are always welcome!
Avalonia is now in alpha. What does "alpha" mean? Well, it means that it's now at a stage where you
can have a play and hopefully create simple applications. There's now a [Visual
Studio Extension](https://marketplace.visualstudio.com/items?itemName=AvaloniaTeam.AvaloniaforVisualStudio)
containing project and item templates that will help you get started, and
there's an initial complement of controls. There's still a lot missing, and you
*will* find bugs, and the API *will* change, but this represents the first time
where we've made it somewhat easy to have a play and experiment with the
framework.
## Building and Using
## Documentation
See the [build instructions here](http://avaloniaui.net/contributing/build).
As mentioned above, Avalonia is still in alpha and as such there's not much documentation yet. You can
take a look at the [getting started page](docs/tutorial/gettingstarted.md) for an
overview of how to get started but probably the best thing to do for now is to already know a little bit
about WPF/Silverlight/UWP/XAML and ask questions in our [Gitter room](https://gitter.im/AvaloniaUI/Avalonia).
## Contributing
There's also a high-level [architecture document](docs/spec/architecture.md) that is currently a little bit
out of date, and I've also started writing blog posts on Avalonia at http://grokys.github.io/.
Please read the [contribution guidelines](http://avaloniaui.net/contributing/contributing) before submitting a pull request.
Contributions are always welcome!
### Contributors
## Building and Using
This project exists thanks to all the people who contribute. [[Contribute](http://avaloniaui.net/contributing/contributing)].
<a href="https://github.com/AvaloniaUI/Avalonia/graphs/contributors"><img src="https://opencollective.com/Avalonia/contributors.svg?width=890&button=false" /></a>
### Backers
Thank you to all our backers! 🙏 [[Become a backer](https://opencollective.com/Avalonia#backer)]
<a href="https://opencollective.com/Avalonia#backers" target="_blank"><img src="https://opencollective.com/Avalonia/backers.svg?width=890"></a>
### Sponsors
Support this project by becoming a sponsor. Your logo will show up here with a link to your website. [[Become a sponsor](https://opencollective.com/Avalonia#sponsor)]
See the [build instructions here](docs/guidelines/build.md)
<a href="https://opencollective.com/Avalonia/sponsor/0/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/0/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/1/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/1/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/2/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/2/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/3/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/3/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/4/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/4/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/5/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/5/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/6/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/6/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/7/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/7/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/8/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/8/avatar.svg"></a>
<a href="https://opencollective.com/Avalonia/sponsor/9/website" target="_blank"><img src="https://opencollective.com/Avalonia/sponsor/9/avatar.svg"></a>
## Contributing ##
Please read the [contribution guidelines](docs/guidelines/contributing.md) before submitting a pull request.

16
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.7"/>
</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>

14
samples/BindingTest/App.xaml.cs

@ -16,21 +16,11 @@ namespace BindingTest
private static void Main()
{
InitializeLogging();
AppBuilder.Configure<App>()
.UsePlatformDetect()
.UseReactiveUI()
.LogToDebug()
.Start<MainWindow>();
}
private static void InitializeLogging()
{
#if DEBUG
SerilogLogger.Initialize(new LoggerConfiguration()
.MinimumLevel.Warning()
.WriteTo.Trace(outputTemplate: "{Area}: {Message}")
.CreateLogger());
#endif
}
}
}

186
samples/BindingTest/BindingTest.csproj

@ -1,166 +1,34 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{08B3E6B9-1CD5-443C-9F61-6D49D1C5F162}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>BindingTest</RootNamespace>
<AssemblyName>BindingTest</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<OutputType>Exe</OutputType>
<TargetFrameworks>netcoreapp2.0;net461</TargetFrameworks>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="App.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="TestItemView.xaml.cs">
<DependentUpon>TestItemView.xaml</DependentUpon>
</Compile>
<Compile Include="ViewModels\DataAnnotationsErrorViewModel.cs" />
<Compile Include="ViewModels\IndeiErrorViewModel.cs" />
<Compile Include="ViewModels\ExceptionErrorViewModel.cs" />
<Compile Include="ViewModels\MainWindowViewModel.cs" />
<Compile Include="ViewModels\TestItem.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<EmbeddedResource Include="MainWindow.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="TestItemView.xaml" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
<Project>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</Project>
<Name>Avalonia.DotNetFrameworkRuntime</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
<Project>{3e53a01a-b331-47f3-b828-4a5717e77a24}</Project>
<Name>Avalonia.Markup.Xaml</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
<Project>{6417e941-21bc-467b-a771-0de389353ce6}</Project>
<Name>Avalonia.Markup</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj">
<Project>{d211e587-d8bc-45b9-95a4-f297c8fa5200}</Project>
<Name>Avalonia.Animation</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj">
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project>
<Name>Avalonia.Base</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj">
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project>
<Name>Avalonia.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj">
<Project>{799a7bb5-3c2c-48b6-85a7-406a12c420da}</Project>
<Name>Avalonia.DesignerSupport</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj">
<Project>{7062ae20-5dcc-4442-9645-8195bdece63e}</Project>
<Name>Avalonia.Diagnostics</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Name>Avalonia.Input</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Name>Avalonia.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Name>Avalonia.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Logging.Serilog\Avalonia.Logging.Serilog.csproj">
<Project>{b61b66a3-b82d-4875-8001-89d3394fe0c9}</Project>
<Name>Avalonia.Logging.Serilog</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj">
<Project>{6417b24e-49c2-4985-8db2-3ab9d898ec91}</Project>
<Name>Avalonia.ReactiveUI</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Name>Avalonia.Visuals</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj">
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project>
<Name>Avalonia.Styling</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj">
<Project>{3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f}</Project>
<Name>Avalonia.Themes.Default</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" Condition="'$(Platform)'!='Mono'">
<Project>{3e908f67-5543-4879-a1dc-08eace79b3cd}</Project>
<Name>Avalonia.Direct2D1</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" Condition="'$(Platform)'!='Mono'">
<Project>{811a76cf-1cf6-440f-963b-bbe31bd72a82}</Project>
<Name>Avalonia.Win32</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Gtk\Avalonia.Gtk\Avalonia.Gtk.csproj">
<Project>{54F237D5-A70A-4752-9656-0C70B1A7B047}</Project>
<Name>Avalonia.Gtk</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Gtk\Avalonia.Cairo\Avalonia.Cairo.csproj">
<Project>{FB05AC90-89BA-4F2F-A924-F37875FB547C}</Project>
<Name>Avalonia.Cairo</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" />
<ProjectReference Condition="'$(TargetFramework)'=='netcoreapp2.0'" Include="..\..\src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj" />
<ProjectReference Condition="'$(TargetFramework)'=='net461'" Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj" />
<ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj" />
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj" />
<ProjectReference Include="..\..\src\Avalonia.ReactiveUI\Avalonia.ReactiveUI.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Logging.Serilog\Avalonia.Logging.Serilog.csproj" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\build\SampleApp.props" />
<Import Project="..\..\build\EmbedXaml.props" />
<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" />
<Import Project="..\..\build\ReactiveUI.props" />
</Project>

20
samples/BindingTest/MainWindow.xaml

@ -1,11 +1,18 @@
<Window xmlns="https://github.com/avaloniaui"
xmlns:vm="clr-namespace:BindingTest.ViewModels;assembly=BindingTest"
xmlns:local="clr-namespace:BindingTest;assembly=BindingTest">
xmlns:x='http://schemas.microsoft.com/winfx/2006/xaml'
xmlns:vm="clr-namespace:BindingTest.ViewModels"
xmlns:local="clr-namespace:BindingTest"
Title="AvaloniaUI Bindings Test"
Width="800"
Height="600">
<Window.Styles>
<Style Selector="TextBlock.h1">
<Setter Property="FontSize" Value="18"/>
</Style>
</Window.Styles>
<Window.Resources>
<vm:TestItem x:Key="SharedItem" StringValue="shared" />
</Window.Resources>
<TabControl>
<TabItem Header="Basic">
@ -40,10 +47,16 @@
<TextBlock FontSize="16" Text="Binding Sources"/>
<TextBox Watermark="Value of first TextBox" UseFloatingWatermark="True"
Text="{Binding #first.Text, Mode=TwoWay}"/>
<TextBox Watermark="Value of SharedItem.StringValue" UseFloatingWatermark="True"
Text="{Binding StringValue, Source={StaticResource SharedItem}, Mode=TwoWay}"/>
<TextBox Watermark="Value of SharedItem.StringValue (duplicate)" UseFloatingWatermark="True"
Text="{Binding StringValue, Source={StaticResource SharedItem}, Mode=TwoWay}"/>
</StackPanel>
<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 +108,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>

36
samples/BindingTest/Properties/AssemblyInfo.cs

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("BindingTest")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("BindingTest")]
[assembly: AssemblyCopyright("Copyright © 2015")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("08b3e6b9-1cd5-443c-9f61-6d49d1c5f162")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

22
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()
{
@ -27,18 +28,17 @@ namespace BindingTest.ViewModels
SelectedItems = new ObservableCollection<TestItem>();
ShuffleItems = ReactiveCommand.Create();
ShuffleItems.Subscribe(_ =>
ShuffleItems = ReactiveCommand.Create(() =>
{
var r = new Random();
Items.Move(r.Next(Items.Count), 1);
});
StringValueCommand = ReactiveCommand.Create();
StringValueCommand.Subscribe(param =>
StringValueCommand = ReactiveCommand.Create<object>(param =>
{
BooleanFlag = !BooleanFlag;
StringValue = param.ToString();
NestedModel = _nested ?? new NestedCommandViewModel();
});
Task.Run(() =>
@ -49,11 +49,14 @@ namespace BindingTest.ViewModels
Thread.Sleep(1000);
}
});
CurrentTimeObservable = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(1))
.Select(x => DateTimeOffset.Now.ToString());
}
public ObservableCollection<TestItem> Items { get; }
public ObservableCollection<TestItem> SelectedItems { get; }
public ReactiveCommand<object> ShuffleItems { get; }
public ReactiveCommand ShuffleItems { get; }
public string BooleanString
{
@ -85,10 +88,17 @@ namespace BindingTest.ViewModels
private set { this.RaiseAndSetIfChanged(ref _currentTime, value); }
}
public ReactiveCommand<object> StringValueCommand { get; }
public IObservable<string> CurrentTimeObservable { get; }
public ReactiveCommand 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
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; }
}
}

11
samples/ControlCatalog.Android/ControlCatalog.Android.csproj

@ -111,10 +111,6 @@
<Project>{7062ae20-5dcc-4442-9645-8195bdece63e}</Project>
<Name>Avalonia.Diagnostics</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.HtmlRenderer\Avalonia.HtmlRenderer.csproj">
<Project>{5fb2b005-0a7f-4dad-add4-3ed01444e63d}</Project>
<Name>Avalonia.HtmlRenderer</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Name>Avalonia.Input</Name>
@ -147,9 +143,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 +154,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>

9
samples/ControlCatalog.Android/Resources/Resource.Designer.cs

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

16
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.7"/>
</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>

153
samples/ControlCatalog.Desktop/ControlCatalog.Desktop.csproj

@ -1,148 +1,21 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{2B888490-D14A-4BCA-AB4B-48676FA93C9B}</ProjectGuid>
<OutputType>WinExe</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>ControlCatalog.Desktop</RootNamespace>
<AssemblyName>ControlCatalog.Desktop</AssemblyName>
<TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
<RestoreProjectStyle>PackageReference</RestoreProjectStyle>
<OutputType>Exe</OutputType>
<TargetFramework>net461</TargetFramework>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>x86</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup>
<StartupObject />
</PropertyGroup>
<ItemGroup>
<Reference Include="System" />
<Reference Include="System.Core" />
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
</ItemGroup>
<ItemGroup>
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<ProjectReference Include="..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" />
<ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Logging.Serilog\Avalonia.Logging.Serilog.csproj" />
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj">
<Project>{799a7bb5-3c2c-48b6-85a7-406a12c420da}</Project>
<Name>Avalonia.DesignerSupport</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj">
<Project>{4A1ABB09-9047-4BD5-A4AD-A055E52C5EE0}</Project>
<Name>Avalonia.DotNetFrameworkRuntime</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Gtk\Avalonia.Cairo\Avalonia.Cairo.csproj">
<Project>{FB05AC90-89BA-4F2F-A924-F37875FB547C}</Project>
<Name>Avalonia.Cairo</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Gtk\Avalonia.Gtk3\Avalonia.Gtk3.csproj">
<Project>{bb1f7bb5-6ad4-4776-94d9-c09d0a972658}</Project>
<Name>Avalonia.Gtk3</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Gtk\Avalonia.Gtk\Avalonia.Gtk.csproj">
<Project>{54F237D5-A70A-4752-9656-0C70B1A7B047}</Project>
<Name>Avalonia.Gtk</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj">
<Project>{3E53A01A-B331-47F3-B828-4A5717E77A24}</Project>
<Name>Avalonia.Markup.Xaml</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj">
<Project>{6417E941-21BC-467B-A771-0DE389353CE6}</Project>
<Name>Avalonia.Markup</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj">
<Project>{d211e587-d8bc-45b9-95a4-f297c8fa5200}</Project>
<Name>Avalonia.Animation</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj">
<Project>{B09B78D8-9B26-48B0-9149-D64A2F120F3F}</Project>
<Name>Avalonia.Base</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj">
<Project>{D2221C82-4A25-4583-9B43-D791E3F6820C}</Project>
<Name>Avalonia.Controls</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project>
<Name>Avalonia.Input</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj">
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project>
<Name>Avalonia.Interactivity</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj">
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project>
<Name>Avalonia.Layout</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Logging.Serilog\Avalonia.Logging.Serilog.csproj">
<Project>{B61B66A3-B82D-4875-8001-89D3394FE0C9}</Project>
<Name>Avalonia.Logging.Serilog</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Visuals\Avalonia.Visuals.csproj">
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project>
<Name>Avalonia.Visuals</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj">
<Project>{F1BAA01A-F176-4C6A-B39D-5B40BB1B148F}</Project>
<Name>Avalonia.Styling</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj">
<Project>{3E10A5FA-E8DA-48B1-AD44-6A5B6CB7750F}</Project>
<Name>Avalonia.Themes.Default</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Skia\Avalonia.Skia.Desktop\Avalonia.Skia.Desktop.csproj" Condition="'$(Platform)'!='Mono'">
<Project>{925DD807-B651-475F-9F7C-CBEB974CE43D}</Project>
<Name>Avalonia.Skia.Desktop</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Windows\Avalonia.Direct2D1\Avalonia.Direct2D1.csproj" Condition="'$(Platform)'!='Mono'">
<Project>{3E908F67-5543-4879-A1DC-08EACE79B3CD}</Project>
<Name>Avalonia.Direct2D1</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Windows\Avalonia.Win32\Avalonia.Win32.csproj" Condition="'$(Platform)'!='Mono'">
<Project>{811A76CF-1CF6-440F-963B-BBE31BD72A82}</Project>
<Name>Avalonia.Win32</Name>
</ProjectReference>
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj">
<Project>{d0a739b9-3c68-4ba6-a328-41606954b6bd}</Project>
<Name>ControlCatalog</Name>
</ProjectReference>
<Folder Include="Properties\" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\build\SampleApp.props" />
<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>

22
samples/ControlCatalog.Desktop/Program.cs

@ -10,27 +10,19 @@ namespace ControlCatalog
{
internal class Program
{
[STAThread]
static void Main(string[] args)
{
InitializeLogging();
// TODO: Make this work with GTK/Skia/Cairo depending on command-line args
// again.
AppBuilder.Configure<App>()
.UsePlatformDetect()
.Start<MainWindow>();
BuildAvaloniaApp().Start<MainWindow>();
}
// This will be made into a runtime configuration extension soon!
private static void InitializeLogging()
{
#if DEBUG
SerilogLogger.Initialize(new LoggerConfiguration()
.MinimumLevel.Warning()
.WriteTo.Trace(outputTemplate: "{Area}: {Message}")
.CreateLogger());
#endif
}
/// <summary>
/// This method is needed for IDE previewer infrastructure
/// </summary>
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>().LogToDebug().UsePlatformDetect();
private static void ConfigureAssetAssembly(AppBuilder builder)
{

36
samples/ControlCatalog.Desktop/Properties/AssemblyInfo.cs

@ -1,36 +0,0 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("ControlCatalog.Desktop")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("ControlCatalog.Desktop")]
[assembly: AssemblyCopyright("Copyright © 2016")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("2b888490-d14a-4bca-ab4b-48676fa93c9b")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

3
samples/ControlCatalog.NetCore/ControlCatalog.NetCore.csproj

@ -2,10 +2,11 @@
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp1.1</TargetFramework>
<TargetFramework>netcoreapp2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Avalonia.DesignerSupport\Avalonia.DesignerSupport.csproj" />
<ProjectReference Include="..\..\src\Avalonia.DotNetCoreRuntime\Avalonia.DotNetCoreRuntime.csproj" />
<ProjectReference Include="..\..\src\Linux\Avalonia.LinuxFramebuffer\Avalonia.LinuxFramebuffer.csproj" />
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj" />

36
samples/ControlCatalog.NetCore/Program.cs

@ -1,24 +1,44 @@
using System;
using System.Diagnostics;
using System.Linq;
using System.Runtime.InteropServices;
using System.Threading;
using Avalonia;
namespace ControlCatalog.NetCore
{
class Program
static class Program
{
static void Main(string[] args)
{
if (args.Contains("--fbdev")) AppBuilder.Configure<App>().InitializeWithLinuxFramebuffer(tl =>
Thread.CurrentThread.TrySetApartmentState(ApartmentState.STA);
if (args.Contains("--wait-for-attach"))
{
tl.Content = new MainView();
System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer());
});
Console.WriteLine("Attach debugger and use 'Set next statement'");
while (true)
{
Thread.Sleep(100);
if (Debugger.IsAttached)
break;
}
}
if (args.Contains("--fbdev"))
AppBuilder.Configure<App>().InitializeWithLinuxFramebuffer(tl =>
{
tl.Content = new MainView();
System.Threading.ThreadPool.QueueUserWorkItem(_ => ConsoleSilencer());
});
else
AppBuilder.Configure<App>()
.UsePlatformDetect()
.Start<MainWindow>();
BuildAvaloniaApp().Start<MainWindow>();
}
/// <summary>
/// This method is needed for IDE previewer infrastructure
/// </summary>
public static AppBuilder BuildAvaloniaApp()
=> AppBuilder.Configure<App>().UsePlatformDetect().UseReactiveUI();
static void ConsoleSilencer()
{
Console.CursorVisible = false;

14
samples/ControlCatalog.iOS/ControlCatalog.iOS.csproj

@ -141,10 +141,6 @@
<Project>{7062AE20-5DCC-4442-9645-8195BDECE63E}</Project>
<Name>Avalonia.Diagnostics</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.HtmlRenderer\Avalonia.HtmlRenderer.csproj">
<Project>{5FB2B005-0A7F-4DAD-ADD4-3ED01444E63D}</Project>
<Name>Avalonia.HtmlRenderer</Name>
</ProjectReference>
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj">
<Project>{62024B2D-53EB-4638-B26B-85EEAA54866E}</Project>
<Name>Avalonia.Input</Name>
@ -169,17 +165,15 @@
<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>
<IsAppExtension>false</IsAppExtension>
<IsWatchApp>false</IsWatchApp>
<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>
<Name>ControlCatalog</Name>
</ProjectReference>
</ItemGroup>
<Import Project="..\..\build\Sprache.props" />
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
<Import Project="$(MSBuildThisFileDirectory)..\..\src\Shared\nuget.workaround.targets" />
</Project>

BIN
samples/ControlCatalog/Assets/Fonts/SourceSansPro-Bold.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Assets/Fonts/SourceSansPro-BoldItalic.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Assets/Fonts/SourceSansPro-Italic.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Assets/Fonts/SourceSansPro-Regular.ttf

Binary file not shown.

BIN
samples/ControlCatalog/Assets/test_icon.ico

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 172 KiB

161
samples/ControlCatalog/ControlCatalog.csproj

@ -1,145 +1,23 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard1.1</TargetFramework>
<EnableDefaultCompileItems>False</EnableDefaultCompileItems>
<GenerateAssemblyInfo>false</GenerateAssemblyInfo>
</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>
</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>
<TargetFramework>netstandard2.0</TargetFramework>
</PropertyGroup>
<ItemGroup>
<!-- A reference to the entire .NET Framework is automatically included -->
<EmbeddedResource Include="App.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="MainView.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\BorderPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\ButtonPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\CanvasPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\CarouselPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\CheckBoxPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\DropDownPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\ExpanderPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\ImagePage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\LayoutTransformControlPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\MenuPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\RadioButtonPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\SliderPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\TextBoxPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Pages\ToolTipPage.xaml">
<Compile Update="**\*.xaml.cs">
<DependentUpon>%(Filename)</DependentUpon>
</Compile>
<EmbeddedResource Include="**\*.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Assets\*" />
</ItemGroup>
<ItemGroup>
<Compile Include="App.xaml.cs">
<DependentUpon>App.xaml</DependentUpon>
</Compile>
<Compile Include="MainView.xaml.cs">
<DependentUpon>MainView.xaml</DependentUpon>
</Compile>
<Compile Include="MainWindow.xaml.cs">
<DependentUpon>MainWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\BorderPage.xaml.cs">
<DependentUpon>BorderPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\ButtonPage.xaml.cs">
<DependentUpon>ButtonPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\CanvasPage.xaml.cs">
<DependentUpon>CanvasPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\CarouselPage.xaml.cs">
<DependentUpon>CarouselPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\CheckBoxPage.xaml.cs">
<DependentUpon>CheckBoxPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\DropDownPage.xaml.cs">
<DependentUpon>DropDownPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\ExpanderPage.xaml.cs">
<DependentUpon>ExpanderPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\ImagePage.xaml.cs">
<DependentUpon>ImagePage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\LayoutTransformControlPage.xaml.cs">
<DependentUpon>LayoutTransformControlPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\MenuPage.xaml.cs">
<DependentUpon>MenuPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\RadioButtonPage.xaml.cs">
<DependentUpon>RadioButtonPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\SliderPage.xaml.cs">
<DependentUpon>SliderPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\TreeViewPage.xaml.cs">
<DependentUpon>TreeViewPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\TextBoxPage.xaml.cs">
<DependentUpon>TextBoxPage.xaml</DependentUpon>
</Compile>
<Compile Include="Pages\ToolTipPage.xaml.cs">
<DependentUpon>ToolTipPage.xaml</DependentUpon>
</Compile>
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Assets\delicate-arch-896885_640.jpg" />
<EmbeddedResource Include="Assets\github_icon.png" />
<EmbeddedResource Include="Assets\hirsch-899118_640.jpg" />
<EmbeddedResource Include="Assets\maple-leaf-888807_640.jpg" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="SideBar.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
<EmbeddedResource Include="Assets\Fonts\SourceSansPro-Bold.ttf" />
<EmbeddedResource Include="Assets\Fonts\SourceSansPro-BoldItalic.ttf" />
<EmbeddedResource Include="Assets\Fonts\SourceSansPro-Italic.ttf" />
<EmbeddedResource Include="Assets\Fonts\SourceSansPro-Regular.ttf" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj" />
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup\Avalonia.Markup.csproj" />
@ -147,7 +25,6 @@
<ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj" />
<ProjectReference Include="..\..\src\Avalonia.HtmlRenderer\Avalonia.HtmlRenderer.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj" />
@ -156,20 +33,6 @@
<ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj" />
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Assets\test_icon.ico" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="Pages\TreeViewPage.xaml">
<SubType>Designer</SubType>
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="MainWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>
</SubType>
</EmbeddedResource>
</ItemGroup>
<Import Project="..\..\build\Serilog.props" />
</Project>

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save