Browse Source
Conflicts: src/Android/Avalonia.Android/AndroidPlatform.cs src/Avalonia.Controls/TopLevel.cspull/773/head
142 changed files with 2301 additions and 790 deletions
@ -0,0 +1,156 @@ |
|||||
|
# 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" } |
||||
|
}; |
||||
|
``` |
||||
|
|
||||
@ -0,0 +1,99 @@ |
|||||
|
# 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.* |
||||
@ -0,0 +1,19 @@ |
|||||
|
Any raw assets you want to be deployed with your application can be placed in |
||||
|
this directory (and child directories) and given a Build Action of "AndroidAsset". |
||||
|
|
||||
|
These files will be deployed with you package and will be accessible using Android's |
||||
|
AssetManager, like this: |
||||
|
|
||||
|
public class ReadAsset : Activity |
||||
|
{ |
||||
|
protected override void OnCreate (Bundle bundle) |
||||
|
{ |
||||
|
base.OnCreate (bundle); |
||||
|
|
||||
|
InputStream input = Assets.Open ("my_asset.txt"); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
Additionally, some Android functions will automatically load asset files: |
||||
|
|
||||
|
Typeface tf = Typeface.CreateFromAsset (Context.Assets, "fonts/samplefont.ttf"); |
||||
@ -0,0 +1,169 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> |
||||
|
<PropertyGroup> |
||||
|
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration> |
||||
|
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform> |
||||
|
<ProductVersion>8.0.30703</ProductVersion> |
||||
|
<SchemaVersion>2.0</SchemaVersion> |
||||
|
<ProjectGuid>{29132311-1848-4FD6-AE0C-4FF841151BD3}</ProjectGuid> |
||||
|
<ProjectTypeGuids>{EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids> |
||||
|
<OutputType>Library</OutputType> |
||||
|
<AppDesignerFolder>Properties</AppDesignerFolder> |
||||
|
<RootNamespace>ControlCatalog.Android</RootNamespace> |
||||
|
<AssemblyName>ControlCatalog.Android</AssemblyName> |
||||
|
<FileAlignment>512</FileAlignment> |
||||
|
<AndroidApplication>true</AndroidApplication> |
||||
|
<AndroidResgenFile>Resources\Resource.Designer.cs</AndroidResgenFile> |
||||
|
<GenerateSerializationAssemblies>Off</GenerateSerializationAssemblies> |
||||
|
<AndroidUseLatestPlatformSdk>False</AndroidUseLatestPlatformSdk> |
||||
|
<TargetFrameworkVersion>v4.4</TargetFrameworkVersion> |
||||
|
<AndroidManifest>Properties\AndroidManifest.xml</AndroidManifest> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' "> |
||||
|
<DebugSymbols>True</DebugSymbols> |
||||
|
<DebugType>full</DebugType> |
||||
|
<Optimize>false</Optimize> |
||||
|
<OutputPath>bin\Debug\</OutputPath> |
||||
|
<DefineConstants>DEBUG;TRACE</DefineConstants> |
||||
|
<ErrorReport>prompt</ErrorReport> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
<AndroidUseSharedRuntime>True</AndroidUseSharedRuntime> |
||||
|
<AndroidLinkMode>None</AndroidLinkMode> |
||||
|
<EmbedAssembliesIntoApk>False</EmbedAssembliesIntoApk> |
||||
|
<BundleAssemblies>False</BundleAssemblies> |
||||
|
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi> |
||||
|
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis> |
||||
|
<Debugger>Xamarin</Debugger> |
||||
|
<AndroidEnableMultiDex>False</AndroidEnableMultiDex> |
||||
|
</PropertyGroup> |
||||
|
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> |
||||
|
<DebugType>pdbonly</DebugType> |
||||
|
<Optimize>true</Optimize> |
||||
|
<OutputPath>bin\Release\</OutputPath> |
||||
|
<DefineConstants>TRACE</DefineConstants> |
||||
|
<ErrorReport>prompt</ErrorReport> |
||||
|
<WarningLevel>4</WarningLevel> |
||||
|
<AndroidUseSharedRuntime>False</AndroidUseSharedRuntime> |
||||
|
<AndroidLinkMode>Full</AndroidLinkMode> |
||||
|
<EmbedAssembliesIntoApk>True</EmbedAssembliesIntoApk> |
||||
|
<BundleAssemblies>False</BundleAssemblies> |
||||
|
<AndroidCreatePackagePerAbi>False</AndroidCreatePackagePerAbi> |
||||
|
<AndroidSupportedAbis>armeabi,armeabi-v7a,x86</AndroidSupportedAbis> |
||||
|
<Debugger>Xamarin</Debugger> |
||||
|
<AotAssemblies>False</AotAssemblies> |
||||
|
<EnableLLVM>False</EnableLLVM> |
||||
|
<AndroidEnableMultiDex>False</AndroidEnableMultiDex> |
||||
|
<EnableProguard>False</EnableProguard> |
||||
|
<DebugSymbols>False</DebugSymbols> |
||||
|
</PropertyGroup> |
||||
|
<ItemGroup> |
||||
|
<Reference Include="Mono.Android" /> |
||||
|
<Reference Include="mscorlib" /> |
||||
|
<Reference Include="System" /> |
||||
|
<Reference Include="System.Core" /> |
||||
|
<Reference Include="System.Xml.Linq" /> |
||||
|
<Reference Include="System.Xml" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<Compile Include="MainActivity.cs" /> |
||||
|
<Compile Include="Resources\Resource.Designer.cs" /> |
||||
|
<Compile Include="Properties\AssemblyInfo.cs" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<None Include="GettingStarted.Xamarin" /> |
||||
|
<None Include="Resources\AboutResources.txt" /> |
||||
|
<None Include="Assets\AboutAssets.txt" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<AndroidResource Include="Resources\layout\Main.axml"> |
||||
|
<SubType>Designer</SubType> |
||||
|
</AndroidResource> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<AndroidResource Include="Resources\values\Strings.xml" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<AndroidResource Include="Resources\drawable\Icon.png" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<None Include="Properties\AndroidManifest.xml" /> |
||||
|
</ItemGroup> |
||||
|
<ItemGroup> |
||||
|
<ProjectReference Include="..\..\src\Android\Avalonia.Android\Avalonia.Android.csproj"> |
||||
|
<Project>{7B92AF71-6287-4693-9DCB-BD5B6E927E23}</Project> |
||||
|
<Name>Avalonia.Android</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Animation\Avalonia.Animation.csproj"> |
||||
|
<Project>{d211e587-d8bc-45b9-95a4-f297c8fa5200}</Project> |
||||
|
<Name>Avalonia.Animation</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Base\Avalonia.Base.csproj"> |
||||
|
<Project>{b09b78d8-9b26-48b0-9149-d64a2f120f3f}</Project> |
||||
|
<Name>Avalonia.Base</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Controls\Avalonia.Controls.csproj"> |
||||
|
<Project>{d2221c82-4a25-4583-9b43-d791e3f6820c}</Project> |
||||
|
<Name>Avalonia.Controls</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Diagnostics\Avalonia.Diagnostics.csproj"> |
||||
|
<Project>{7062ae20-5dcc-4442-9645-8195bdece63e}</Project> |
||||
|
<Name>Avalonia.Diagnostics</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.DotNetFrameworkRuntime\Avalonia.DotNetFrameworkRuntime.csproj"> |
||||
|
<Project>{4a1abb09-9047-4bd5-a4ad-a055e52c5ee0}</Project> |
||||
|
<Name>Avalonia.DotNetFrameworkRuntime</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.HtmlRenderer\Avalonia.HtmlRenderer.csproj"> |
||||
|
<Project>{5fb2b005-0a7f-4dad-add4-3ed01444e63d}</Project> |
||||
|
<Name>Avalonia.HtmlRenderer</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Input\Avalonia.Input.csproj"> |
||||
|
<Project>{62024b2d-53eb-4638-b26b-85eeaa54866e}</Project> |
||||
|
<Name>Avalonia.Input</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Interactivity\Avalonia.Interactivity.csproj"> |
||||
|
<Project>{6b0ed19d-a08b-461c-a9d9-a9ee40b0c06b}</Project> |
||||
|
<Name>Avalonia.Interactivity</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Layout\Avalonia.Layout.csproj"> |
||||
|
<Project>{42472427-4774-4c81-8aff-9f27b8e31721}</Project> |
||||
|
<Name>Avalonia.Layout</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.SceneGraph\Avalonia.SceneGraph.csproj"> |
||||
|
<Project>{eb582467-6abb-43a1-b052-e981ba910e3a}</Project> |
||||
|
<Name>Avalonia.SceneGraph</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Styling\Avalonia.Styling.csproj"> |
||||
|
<Project>{f1baa01a-f176-4c6a-b39d-5b40bb1b148f}</Project> |
||||
|
<Name>Avalonia.Styling</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Avalonia.Themes.Default\Avalonia.Themes.Default.csproj"> |
||||
|
<Project>{3e10a5fa-e8da-48b1-ad44-6a5b6cb7750f}</Project> |
||||
|
<Name>Avalonia.Themes.Default</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\..\src\Markup\Avalonia.Markup.Xaml\Avalonia.Markup.Xaml.csproj"> |
||||
|
<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\Skia\Avalonia.Skia.Android\Avalonia.Skia.Android.csproj"> |
||||
|
<Project>{bd43f7c0-396b-4aa1-bad9-dfde54d51298}</Project> |
||||
|
<Name>Avalonia.Skia.Android</Name> |
||||
|
</ProjectReference> |
||||
|
<ProjectReference Include="..\ControlCatalog\ControlCatalog.csproj"> |
||||
|
<Project>{d0a739b9-3c68-4ba6-a328-41606954b6bd}</Project> |
||||
|
<Name>ControlCatalog</Name> |
||||
|
</ProjectReference> |
||||
|
</ItemGroup> |
||||
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" /> |
||||
|
<!-- To modify your build process, add your task inside one of the targets below and uncomment it. |
||||
|
Other similar extension points exist, see Microsoft.Common.targets. |
||||
|
<Target Name="BeforeBuild"> |
||||
|
</Target> |
||||
|
<Target Name="AfterBuild"> |
||||
|
</Target> |
||||
|
--> |
||||
|
</Project> |
||||
@ -0,0 +1,26 @@ |
|||||
|
<ProjectConfiguration> |
||||
|
<AutoDetectNugetBuildDependencies>true</AutoDetectNugetBuildDependencies> |
||||
|
<BuildPriority>1000</BuildPriority> |
||||
|
<CopyReferencedAssembliesToWorkspace>false</CopyReferencedAssembliesToWorkspace> |
||||
|
<ConsiderInconclusiveTestsAsPassing>false</ConsiderInconclusiveTestsAsPassing> |
||||
|
<PreloadReferencedAssemblies>false</PreloadReferencedAssemblies> |
||||
|
<AllowDynamicCodeContractChecking>true</AllowDynamicCodeContractChecking> |
||||
|
<AllowStaticCodeContractChecking>false</AllowStaticCodeContractChecking> |
||||
|
<AllowCodeAnalysis>false</AllowCodeAnalysis> |
||||
|
<IgnoreThisComponentCompletely>true</IgnoreThisComponentCompletely> |
||||
|
<RunPreBuildEvents>false</RunPreBuildEvents> |
||||
|
<RunPostBuildEvents>false</RunPostBuildEvents> |
||||
|
<PreviouslyBuiltSuccessfully>false</PreviouslyBuiltSuccessfully> |
||||
|
<InstrumentAssembly>true</InstrumentAssembly> |
||||
|
<PreventSigningOfAssembly>false</PreventSigningOfAssembly> |
||||
|
<AnalyseExecutionTimes>true</AnalyseExecutionTimes> |
||||
|
<DetectStackOverflow>true</DetectStackOverflow> |
||||
|
<IncludeStaticReferencesInWorkspace>true</IncludeStaticReferencesInWorkspace> |
||||
|
<DefaultTestTimeout>60000</DefaultTestTimeout> |
||||
|
<UseBuildConfiguration /> |
||||
|
<UseBuildPlatform /> |
||||
|
<ProxyProcessPath /> |
||||
|
<UseCPUArchitecture>AutoDetect</UseCPUArchitecture> |
||||
|
<MSTestThreadApartmentState>STA</MSTestThreadApartmentState> |
||||
|
<BuildProcessArchitecture>x86</BuildProcessArchitecture> |
||||
|
</ProjectConfiguration> |
||||
@ -0,0 +1,4 @@ |
|||||
|
<GettingStarted> |
||||
|
<LocalContent>GS\Android\CS\AndroidApp\GettingStarted.html</LocalContent> |
||||
|
<EmbeddedNavigation>false</EmbeddedNavigation> |
||||
|
</GettingStarted> |
||||
@ -0,0 +1,46 @@ |
|||||
|
using System; |
||||
|
using Android.App; |
||||
|
|
||||
|
using Android.OS; |
||||
|
using Android.Content.PM; |
||||
|
using Avalonia.Android.Platform.Specific; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Controls.Templates; |
||||
|
using Avalonia.Markup.Xaml; |
||||
|
using Avalonia.Media; |
||||
|
using Avalonia.Styling; |
||||
|
using Avalonia.Themes.Default; |
||||
|
using Avalonia; |
||||
|
|
||||
|
namespace ControlCatalog.Android |
||||
|
{ |
||||
|
[Activity(Label = "ControlCatalog.Android", MainLauncher = true, Icon = "@drawable/icon", LaunchMode = LaunchMode.SingleInstance)] |
||||
|
public class MainActivity : AvaloniaActivity |
||||
|
{ |
||||
|
public MainActivity() : base(typeof (App)) |
||||
|
{ |
||||
|
|
||||
|
} |
||||
|
|
||||
|
protected override void OnCreate(Bundle savedInstanceState) |
||||
|
{ |
||||
|
base.OnCreate(savedInstanceState); |
||||
|
|
||||
|
App app; |
||||
|
if (Avalonia.Application.Current != null) |
||||
|
app = (App)Avalonia.Application.Current; |
||||
|
else |
||||
|
{ |
||||
|
app = new App(); |
||||
|
AppBuilder.Configure(app) |
||||
|
.UseAndroid() |
||||
|
.UseSkia() |
||||
|
.SetupWithoutStarting(); |
||||
|
} |
||||
|
|
||||
|
var mainWindow = new MainWindow(); |
||||
|
app.Run(mainWindow); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
|
||||
@ -0,0 +1,5 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="ControlCatalog.Android" android:versionCode="1" android:versionName="1.0" android:installLocation="auto"> |
||||
|
<uses-sdk /> |
||||
|
<application android:label="ControlCatalog.Android"></application> |
||||
|
</manifest> |
||||
@ -0,0 +1,30 @@ |
|||||
|
using System.Reflection; |
||||
|
using System.Runtime.CompilerServices; |
||||
|
using System.Runtime.InteropServices; |
||||
|
using Android.App; |
||||
|
|
||||
|
// 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.Android")] |
||||
|
[assembly: AssemblyDescription("")] |
||||
|
[assembly: AssemblyConfiguration("")] |
||||
|
[assembly: AssemblyCompany("")] |
||||
|
[assembly: AssemblyProduct("ControlCatalog.Android")] |
||||
|
[assembly: AssemblyCopyright("Copyright © 2016")] |
||||
|
[assembly: AssemblyTrademark("")] |
||||
|
[assembly: AssemblyCulture("")] |
||||
|
[assembly: ComVisible(false)] |
||||
|
|
||||
|
// 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,44 @@ |
|||||
|
Images, layout descriptions, binary blobs and string dictionaries can be included |
||||
|
in your application as resource files. Various Android APIs are designed to |
||||
|
operate on the resource IDs instead of dealing with images, strings or binary blobs |
||||
|
directly. |
||||
|
|
||||
|
For example, a sample Android app that contains a user interface layout (main.axml), |
||||
|
an internationalization string table (strings.xml) and some icons (drawable-XXX/icon.png) |
||||
|
would keep its resources in the "Resources" directory of the application: |
||||
|
|
||||
|
Resources/ |
||||
|
drawable/ |
||||
|
icon.png |
||||
|
|
||||
|
layout/ |
||||
|
main.axml |
||||
|
|
||||
|
values/ |
||||
|
strings.xml |
||||
|
|
||||
|
In order to get the build system to recognize Android resources, set the build action to |
||||
|
"AndroidResource". The native Android APIs do not operate directly with filenames, but |
||||
|
instead operate on resource IDs. When you compile an Android application that uses resources, |
||||
|
the build system will package the resources for distribution and generate a class called "R" |
||||
|
(this is an Android convention) that contains the tokens for each one of the resources |
||||
|
included. For example, for the above Resources layout, this is what the R class would expose: |
||||
|
|
||||
|
public class R { |
||||
|
public class drawable { |
||||
|
public const int icon = 0x123; |
||||
|
} |
||||
|
|
||||
|
public class layout { |
||||
|
public const int main = 0x456; |
||||
|
} |
||||
|
|
||||
|
public class strings { |
||||
|
public const int first_string = 0xabc; |
||||
|
public const int second_string = 0xbcd; |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
You would then use R.drawable.icon to reference the drawable/icon.png file, or R.layout.main |
||||
|
to reference the layout/main.axml file, or R.strings.first_string to reference the first |
||||
|
string in the dictionary file values/strings.xml. |
||||
@ -0,0 +1,114 @@ |
|||||
|
#pragma warning disable 1591
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
// <auto-generated>
|
||||
|
// This code was generated by a tool.
|
||||
|
// Runtime Version:4.0.30319.42000
|
||||
|
//
|
||||
|
// Changes to this file may cause incorrect behavior and will be lost if
|
||||
|
// the code is regenerated.
|
||||
|
// </auto-generated>
|
||||
|
//------------------------------------------------------------------------------
|
||||
|
|
||||
|
[assembly: global::Android.Runtime.ResourceDesignerAttribute("ControlCatalog.Android.Resource", IsApplication=true)] |
||||
|
|
||||
|
namespace ControlCatalog.Android |
||||
|
{ |
||||
|
|
||||
|
|
||||
|
[System.CodeDom.Compiler.GeneratedCodeAttribute("Xamarin.Android.Build.Tasks", "1.0.0.0")] |
||||
|
public partial class Resource |
||||
|
{ |
||||
|
|
||||
|
static Resource() |
||||
|
{ |
||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
|
} |
||||
|
|
||||
|
public static void UpdateIdValues() |
||||
|
{ |
||||
|
global::Avalonia.Android.Resource.String.ApplicationName = global::ControlCatalog.Android.Resource.String.ApplicationName; |
||||
|
global::Avalonia.Android.Resource.String.Hello = global::ControlCatalog.Android.Resource.String.Hello; |
||||
|
} |
||||
|
|
||||
|
public partial class Attribute |
||||
|
{ |
||||
|
|
||||
|
static Attribute() |
||||
|
{ |
||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
|
} |
||||
|
|
||||
|
private Attribute() |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public partial class Drawable |
||||
|
{ |
||||
|
|
||||
|
// aapt resource value: 0x7f020000
|
||||
|
public const int Icon = 2130837504; |
||||
|
|
||||
|
static Drawable() |
||||
|
{ |
||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
|
} |
||||
|
|
||||
|
private Drawable() |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public partial class Id |
||||
|
{ |
||||
|
|
||||
|
// aapt resource value: 0x7f050000
|
||||
|
public const int MyButton = 2131034112; |
||||
|
|
||||
|
static Id() |
||||
|
{ |
||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
|
} |
||||
|
|
||||
|
private Id() |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public partial class Layout |
||||
|
{ |
||||
|
|
||||
|
// aapt resource value: 0x7f030000
|
||||
|
public const int Main = 2130903040; |
||||
|
|
||||
|
static Layout() |
||||
|
{ |
||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
|
} |
||||
|
|
||||
|
private Layout() |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public partial class String |
||||
|
{ |
||||
|
|
||||
|
// aapt resource value: 0x7f040001
|
||||
|
public const int ApplicationName = 2130968577; |
||||
|
|
||||
|
// aapt resource value: 0x7f040000
|
||||
|
public const int Hello = 2130968576; |
||||
|
|
||||
|
static String() |
||||
|
{ |
||||
|
global::Android.Runtime.ResourceIdManager.UpdateIdValues(); |
||||
|
} |
||||
|
|
||||
|
private String() |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
} |
||||
|
#pragma warning restore 1591
|
||||
|
After Width: | Height: | Size: 4.0 KiB |
@ -0,0 +1,13 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" |
||||
|
android:orientation="vertical" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="match_parent" |
||||
|
> |
||||
|
<Button |
||||
|
android:id="@+id/MyButton" |
||||
|
android:layout_width="match_parent" |
||||
|
android:layout_height="wrap_content" |
||||
|
android:text="@string/Hello" |
||||
|
/> |
||||
|
</LinearLayout> |
||||
@ -0,0 +1,5 @@ |
|||||
|
<?xml version="1.0" encoding="utf-8"?> |
||||
|
<resources> |
||||
|
<string name="Hello">Hello World, Click Me!</string> |
||||
|
<string name="ApplicationName">ControlCatalog.Android</string> |
||||
|
</resources> |
||||
@ -1 +1 @@ |
|||||
Subproject commit b122549406107170bbe6e67c0d6a1a4252beef77 |
Subproject commit 544af79d218127b4174da4be19896c5ca78eaa5d |
||||
@ -0,0 +1,42 @@ |
|||||
|
using System; |
||||
|
using System.Collections.Generic; |
||||
|
using System.Linq; |
||||
|
using Avalonia.Data; |
||||
|
|
||||
|
namespace Avalonia.Markup.Data |
||||
|
{ |
||||
|
internal class MarkupBindingChainException : BindingChainException |
||||
|
{ |
||||
|
private IList<string> _nodes = new List<string>(); |
||||
|
|
||||
|
public MarkupBindingChainException(string message) |
||||
|
: base(message) |
||||
|
{ |
||||
|
} |
||||
|
|
||||
|
public MarkupBindingChainException(string message, string node) |
||||
|
: base(message) |
||||
|
{ |
||||
|
AddNode(node); |
||||
|
} |
||||
|
|
||||
|
public MarkupBindingChainException(string message, string expression, string expressionNullPoint) |
||||
|
: base(message, expression, expressionNullPoint) |
||||
|
{ |
||||
|
_nodes = null; |
||||
|
} |
||||
|
|
||||
|
public bool HasNodes => _nodes.Count > 0; |
||||
|
public void AddNode(string node) => _nodes.Add(node); |
||||
|
|
||||
|
public void Commit(string expression) |
||||
|
{ |
||||
|
Expression = expression; |
||||
|
ExpressionErrorPoint = string.Join(".", _nodes.Reverse()) |
||||
|
.Replace(".!", "!") |
||||
|
.Replace(".[", "[") |
||||
|
.Replace(".^", "^"); |
||||
|
_nodes = null; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -1,33 +0,0 @@ |
|||||
using System.Collections.Generic; |
|
||||
using System.Linq; |
|
||||
using Avalonia.Data; |
|
||||
|
|
||||
namespace Avalonia.Markup.Data |
|
||||
{ |
|
||||
internal class MarkupBindingChainNullException : BindingChainNullException |
|
||||
{ |
|
||||
private IList<string> _nodes = new List<string>(); |
|
||||
|
|
||||
public MarkupBindingChainNullException() |
|
||||
{ |
|
||||
} |
|
||||
|
|
||||
public MarkupBindingChainNullException(string expression, string expressionNullPoint) |
|
||||
: base(expression, expressionNullPoint) |
|
||||
{ |
|
||||
_nodes = null; |
|
||||
} |
|
||||
|
|
||||
public bool HasNodes => _nodes.Count > 0; |
|
||||
public void AddNode(string node) => _nodes.Add(node); |
|
||||
|
|
||||
public void Commit(string expression) |
|
||||
{ |
|
||||
Expression = expression; |
|
||||
ExpressionNullPoint = string.Join(".", _nodes.Reverse()) |
|
||||
.Replace(".!", "!") |
|
||||
.Replace(".[", "["); |
|
||||
_nodes = null; |
|
||||
} |
|
||||
} |
|
||||
} |
|
||||
@ -0,0 +1,31 @@ |
|||||
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
||||
|
|
||||
|
using System; |
||||
|
using System.Globalization; |
||||
|
using Avalonia.Data; |
||||
|
using System.Reactive.Linq; |
||||
|
|
||||
|
namespace Avalonia.Markup.Data |
||||
|
{ |
||||
|
internal class StreamNode : ExpressionNode |
||||
|
{ |
||||
|
public override string Description => "^"; |
||||
|
|
||||
|
protected override IObservable<object> StartListeningCore(WeakReference reference) |
||||
|
{ |
||||
|
foreach (var plugin in ExpressionObserver.StreamHandlers) |
||||
|
{ |
||||
|
if (plugin.Match(reference)) |
||||
|
{ |
||||
|
return plugin.Start(reference); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
// TODO: Improve error.
|
||||
|
return Observable.Return(new BindingNotification( |
||||
|
new MarkupBindingChainException("Stream operator applied to unsupported type", Description), |
||||
|
BindingErrorType.Error)); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,7 @@ |
|||||
|
|
||||
|
namespace Avalonia.Skia.Android.TestApp |
||||
|
{ |
||||
|
public class App : Application |
||||
|
{ |
||||
|
} |
||||
|
} |
||||
Some files were not shown because too many files changed in this diff
Loading…
Reference in new issue