@ -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 |
|||
@ -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 |
|||
|
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -1,6 +1,9 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<DefaultTestTimeout>1000</DefaultTestTimeout> |
|||
<AdditionalFilesToIncludeForProject> |
|||
<Value>..\TestFiles\Direct2D1\**.*</Value> |
|||
</AdditionalFilesToIncludeForProject> |
|||
<DefaultTestTimeout>3000</DefaultTestTimeout> |
|||
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -1,5 +1,3 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
<Settings /> |
|||
</ProjectConfiguration> |
|||
@ -1,5 +1,3 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
<Settings /> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,9 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoredTests> |
|||
<NamedTestSelector> |
|||
<TestName>Avalonia.Markup.UnitTests.Data.Plugins.DataAnnotationsValidationPluginTests.Produces_Aggregate_BindingNotificationsx</TestName> |
|||
</NamedTestSelector> |
|||
</IgnoredTests> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -1,6 +1,9 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<DefaultTestTimeout>1000</DefaultTestTimeout> |
|||
<AdditionalFilesToIncludeForProject> |
|||
<Value>..\TestFiles\Skia\**.*</Value> |
|||
</AdditionalFilesToIncludeForProject> |
|||
<DefaultTestTimeout>3000</DefaultTestTimeout> |
|||
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<PreviouslyBuiltSuccessfully>True</PreviouslyBuiltSuccessfully> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -1,5 +1,3 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
<Settings /> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -0,0 +1,5 @@ |
|||
<ProjectConfiguration> |
|||
<Settings> |
|||
<IgnoreThisComponentCompletely>True</IgnoreThisComponentCompletely> |
|||
</Settings> |
|||
</ProjectConfiguration> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
@ -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> |
|||
|
|||
@ -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> |
|||
|
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
|
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
|
|||
@ -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 © 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> |
|||
@ -1,8 +1,9 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="SharpDX" Version="3.1.1" /> |
|||
<PackageReference Include="SharpDX.Direct2D1" Version="3.1.1" /> |
|||
<PackageReference Include="SharpDX.Direct3D11" Version="3.1.1" /> |
|||
<PackageReference Include="SharpDX.DXGI" Version="3.1.1" /> |
|||
<PackageReference Include="SharpDX" Version="4.0.1" /> |
|||
<PackageReference Include="SharpDX.Direct2D1" Version="4.0.1" /> |
|||
<PackageReference Include="SharpDX.Direct3D11" Version="4.0.1" /> |
|||
<PackageReference Include="SharpDX.DXGI" Version="4.0.1" /> |
|||
<PackageReference Include="SharpDX.Direct3D9" Version="4.0.1" Condition="'$(UseDirect3D9)' == 'true'" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -1,6 +1,6 @@ |
|||
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
|||
<ItemGroup> |
|||
<PackageReference Include="SkiaSharp" Version="1.57.1" /> |
|||
<PackageReference Condition="$(TargetFramework.Trim('.').ToLower().StartsWith('netframework'))" Include="Avalonia.Skia.Linux.Natives" Version="1.57.1.3" /> |
|||
<PackageReference Condition="'$(IncludeLinuxSkia)' == 'true'" Include="Avalonia.Skia.Linux.Natives" Version="1.57.1.3" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
|
|||
@ -0,0 +1,5 @@ |
|||
<Project> |
|||
<ItemGroup> |
|||
<PackageReference Include="SourceLink.Create.CommandLine" Version="2.8.0" PrivateAssets="All" /> |
|||
</ItemGroup> |
|||
</Project> |
|||
@ -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> |
|||
@ -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> |
|||
@ -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> |
|||
|
|||
@ -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 |
|||
@ -1,3 +0,0 @@ |
|||
#docfx |
|||
_site |
|||
api |
|||
@ -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`. |
|||
@ -1,3 +0,0 @@ |
|||
@echo off |
|||
docfx metadata |
|||
docfx build |
|||
@ -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"] |
|||
} |
|||
} |
|||
@ -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! |
|||
@ -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() |
|||
@ -1,4 +0,0 @@ |
|||
- name: Building Avalonia |
|||
href: build.md |
|||
- name: Contributing |
|||
href: contributing.md |
|||
|
Before Width: | Height: | Size: 133 KiB |
|
Before Width: | Height: | Size: 45 KiB |
|
Before Width: | Height: | Size: 122 KiB |
|
Before Width: | Height: | Size: 226 KiB |
|
Before Width: | Height: | Size: 27 KiB |
@ -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 :) ): |
|||
|
|||
 |
|||
|
|||
Creating a Avalonia Project will give you a simple project with a single XAML window. We even have a simple designer: |
|||
|
|||
 |
|||
|
|||
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. |
|||
|
|||
 |
|||
|
|||
## Inspection support |
|||
|
|||
 |
|||
@ -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: |
|||
|
|||
 |
|||
|
|||
## 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! |
|||
@ -1,2 +0,0 @@ |
|||
@echo off |
|||
docfx serve _site |
|||
@ -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. |
|||
|
|||
@ -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" } |
|||
}; |
|||
``` |
|||
|
|||
@ -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.* |
|||
@ -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 |
|||
@ -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` |
|||
@ -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`. |
|||
@ -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 |
|||
@ -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. |
|||
} |
|||
``` |
|||
@ -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> |
|||
@ -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/ |
|||
@ -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: |
|||
 |
|||
|
|||
In Avalonia: |
|||
 |
|||
|
|||
In AvaloniaUI, to get the same scale transform we should indicate that the RenderTransformOrigin is the TopLeft part of the Visual. |
|||
@ -1,10 +0,0 @@ |
|||
# Getting Started |
|||
|
|||
## Windows |
|||
|
|||
 |
|||
|
|||
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 :) ): |
|||
|
Before Width: | Height: | Size: 45 KiB |
@ -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) |
|||
@ -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 |
|||
@ -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> |
|||
@ -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")] |
|||
@ -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; } |
|||
} |
|||
} |
|||
@ -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> |
|||
@ -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")] |
|||
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 172 KiB |