Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Christmas docs #242

Merged
merged 14 commits into from
Dec 24, 2021
43 changes: 40 additions & 3 deletions docs/TOC.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
- name: Supported platforms
href: supported-platforms.md
- name: Get started
expanded: true
items:
- name: Installation
href: get-started/installation.md
Expand All @@ -15,14 +14,52 @@
- name: Migrate from Xamarin.Forms
href: get-started/migrate.md
- name: Fundamentals
expanded: true
items:
- name: Accessibility
href: fundamentals/accessibility.md
- name: App startup
href: fundamentals/app-startup.md
- name: Single project
href: fundamentals/single-project.md
- name: User interface
expanded: true
items:
- name: Controls
items:
- name: BlazorWebView
href: user-interface/controls/blazorwebview.md
- name: Border
href: user-interface/controls/border.md
- name: GraphicsView
href: user-interface/controls/graphicsview.md
- name: Customize controls
href: user-interface/handlers/customize.md
- name: Graphics
items:
- name: Overview
href: user-interface/graphics/index.md
- name: Blend modes
href: user-interface/graphics/blendmodes.md
- name: Colors
href: user-interface/graphics/colors.md
- name: Draw graphical objects
href: user-interface/graphics/draw.md
- name: Images
href: user-interface/graphics/images.md
- name: Paint graphical objects
href: user-interface/graphics/paint.md
- name: Transforms
href: user-interface/graphics/transforms.md
- name: Winding modes
href: user-interface/graphics/windingmodes.md
- name: Images
items:
- name: Splash screen
href: user-interface/images/splashscreen.md
- name: Shadows
href: user-interface/shadow.md
- name: Platform integration
items:
- name: Configure multi-targeting
href: platform-integration/configure-multi-targeting.md
- name: Invoke platform code
href: platform-integration/invoke-platform-code.md
411 changes: 411 additions & 0 deletions docs/fundamentals/accessibility.md

Large diffs are not rendered by default.

26 changes: 23 additions & 3 deletions docs/index.yml
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,7 @@ metadata:
title: .NET Multi-Platform App UI documentation
description: .NET Multi-platform App UI (.NET MAUI) lets you build native apps using a .NET cross-platform UI toolkit that targets the mobile and desktop form factors on Android, iOS, macOS, Windows, and Tizen.
ms.topic: landing-page
author: davidbritch
ms.author: dabritch
ms.date: 06/08/2021
ms.date: 12/24/2021

landingContent:
- title: Overview
Expand All @@ -36,6 +34,8 @@ landingContent:
linkLists:
- linkListType: concept
links:
- text: Accessibility
url: fundamentals/accessibility.md
- text: App startup
url: fundamentals/app-startup.md
- text: Single project
Expand All @@ -44,5 +44,25 @@ landingContent:
linkLists:
- linkListType: concept
links:
- text: BlazorWebView
url: user-interface/controls/blazorwebview.md
- text: Border
url: user-interface/controls/border.md
- text: GraphicsView
url: user-interface/controls/graphicsview.md
- text: Customize controls
url: user-interface/handlers/customize.md
- text: Graphics
url: user-interface/graphics/index.md
- text: Shadows
url: user-interface/shadow.md
- text: Splash screen
url: user-interface/images/splashscreen.md
- title: Platform integration
linkLists:
- linkListType: concept
links:
- text: Configure multi-targeting
url: platform-integration/configure-multi-targeting.md
- text: Invoke platform code
url: platform-integration/invoke-platform-code.md
112 changes: 112 additions & 0 deletions docs/platform-integration/configure-multi-targeting.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
---
title: "Configure .NET MAUI multi-targeting"
description: "Learn how to configure multi-targeting in a .NET MAUI app, based on your own filename and folder criteria."
ms.date: 11/29/2021
---

# Configure multi-targeting

.NET Multi-platform App UI (.NET MAUI) apps use multi-targeting to target multiple platforms from a single project.

[!INCLUDE [docs under construction](~/includes/preview-note.md)]

The project for a .NET MAUI app contains a _Platforms_ folder, with each child folder representing a platform that .NET MAUI can target:

:::image type="content" source="media/configure-multi-targeting/platform-folders.png" alt-text="Platform folders screenshot.":::

The folders for each target platform contain platform-specific code that starts the app on each platform, plus any additional platform code you add. At build time, the build system only includes the code from each folder when building for that specific platform. For example, when you build for Android the files in the _Platforms_ > _Android_ folder will be built into the app package, but the files in the other _Platforms_ folders won't be.

In addition to this default multi-targeting approach, .NET MAUI apps can also be multi-targeted based on your own filename and folder criteria. This enables you to structure your .NET MAUI app project so that you don't have to place your platform code into sub-folders of the _Platforms_ folder.

## Configure filename-based multi-targeting

A standard multi-targeting pattern is to include the platform as an extension in the filename for the platform code. For example, _MyService.Android.cs_ would represent an Android-specific implementation of the `MyService` class. The build system can be configured to use this pattern by adding the following XML to your .NET MAUI app project (.csproj) file as children of the `<Project>` node:

```xml
<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-android')) != true">
<Compile Remove="**\**\*.Android.cs" />
<None Include="**\**\*.Android.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-ios')) != true AND $(TargetFramework.StartsWith('net6.0-maccatalyst')) != true">
<Compile Remove="**\**\*.iOS.cs" />
<None Include="**\**\*.iOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true ">
<Compile Remove="**\*.Windows.cs" />
<None Include="**\*.Windows.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
```

This XML configures the build system to remove platform-based filename patterns under specific conditions:

- Don't compile C# code whose filename ends with _.Android.cs_, if you aren't building for Android.
- Don't compile C# code whose filename ends with _.iOS.cs_, if you aren't building for iOS or MacCatalyst.
- Don't compile C# code whose filename ends with _.Windows.cs_, if you aren't building for Windows.

> [!IMPORTANT]
> Filename-based multi-targeting can be combined with folder-based multi-targeting. For more information, see [Combine filename and folder multi-targeting](#combine-filename-and-folder-multi-targeting).

## Configure folder-based multi-targeting

Another standard multi-targeting pattern is to include the platform as a folder name. For example, a folder named _Android_ would contain Android-specific code. The build system can be configured to use this pattern by adding the following XML to your .NET MAUI app project (.csproj) file as children of the `<Project>` node:

```xml
<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-android')) != true">
<Compile Remove="**\Android\**\*.cs" />
<None Include="**\Android\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-ios')) != true AND $(TargetFramework.StartsWith('net6.0-maccatalyst')) != true">
<Compile Remove="**\iOS\**\*.cs" />
<None Include="**\iOS\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true ">
<Compile Remove="**\Windows\**\*.cs" />
<None Include="**\Windows\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
```

This XML configures the build system to remove platform-based folder patterns under specific conditions:

- Don't compile C# code that's located in the _Android_ folder, or sub-folder of the _Android_ folder, if you aren't building for Android.
- Don't compile C# code that's located in the _iOS_ folder, or sub-folder of the _iOS_ folder, if you aren't building for iOS or MacCatalyst.
- Don't compile C# code that's located in the _Windows_ folder, or sub-folder of the _Windows_ folder, if you aren't building for Windows.

> [!IMPORTANT]
> Folder-based multi-targeting can be combined with filename-based multi-targeting. For more information, see [Combine filename and folder multi-targeting](#combine-filename-and-folder-multi-targeting).

## Combine filename and folder multi-targeting

Filename-based multi-targeting can be combined with folder-based multi-targeting if required. The build system can be configured to use this pattern by adding the following XML to your .NET MAUI app project (.csproj) file as children of the `<Project>` node:

```xml
<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-android')) != true">
<Compile Remove="**\**\*.Android.cs" />
<None Include="**\**\*.Android.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<Compile Remove="**\Android\**\*.cs" />
<None Include="**\Android\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.StartsWith('net6.0-ios')) != true AND $(TargetFramework.StartsWith('net6.0-maccatalyst')) != true">
<Compile Remove="**\**\*.iOS.cs" />
<None Include="**\**\*.iOS.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<Compile Remove="**\iOS\**\*.cs" />
<None Include="**\iOS\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.Contains('-windows')) != true ">
<Compile Remove="**\*.Windows.cs" />
<None Include="**\*.Windows.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
<Compile Remove="**\Windows\**\*.cs" />
<None Include="**\Windows\**\*.cs" Exclude="$(DefaultItemExcludes);$(DefaultExcludesInProjectFolder)" />
</ItemGroup>
```

This XML configures the build system to remove platform-based filename and folder patterns under specific conditions:

- Don't compile C# code whose filename ends with _.Android.cs_, or that's located in the _Android_ folder or sub-folder of the _Android_ folder, if you aren't building for Android.
- Don't compile C# code whose filename ends with _.iOS.cs_, or that's located in the _iOS_ folder or sub-folder of the _iOS_ folder, if you aren't building for iOS or MacCatalyst.
- Don't compile C# code whose filename ends with _.Windows.cs_, or that's located in the _Windows_ folder or sub-folder of the _Windows_ folder, if you aren't building for Windows.
143 changes: 143 additions & 0 deletions docs/platform-integration/invoke-platform-code.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
---
title: ".NET MAUI invoking platform code"
description: "Learn how to invoke platform code in a .NET MAUI app, by combining multi-targeting with partial classes and partial methods."
ms.date: 12/13/2021
---

# Invoke platform code

.NET Multi-platform App UI (.NET MAUI) apps can combine multi-targeting with partial classes and partial methods to invoke platform code from cross-platform code.

[!INCLUDE [docs under construction](~/includes/preview-note.md)]

The project for a .NET MAUI app contains a _Platforms_ folder, with each child folder representing a platform that .NET MAUI can target:

:::image type="content" source="media/invoke-platform-code/platform-folders.png" alt-text="Platform folders screenshot.":::

The folders for each target platform contain platform-specific code that starts the app on each platform, plus any additional platform code you add. At build time, the build system only includes the code from each folder when building for that specific platform. For example, when you build for Android the files in the _Platforms_ > _Android_ folder will be built into the app package, but the files in the other _Platforms_ folders won't be. This approach uses a feature called multi-targeting to target multiple platforms from a single project.

Multi-targeting can be combined with partial classes and partial methods to invoke platform functionality from cross-platform code. The process for invoking platform code from cross-platform code is to:

1. Define the cross-platform API as a partial class that defines partial method signatures for any operations you want to invoke on each platform. For more information, see [Define the cross-platform API](#define-the-cross-platform-api).
1. Implement the cross-platform API per platform, by defining the same partial class and the same partial method signatures, while also providing the method implementations. For more information, see [Implement the API per platform](#implement-the-api-per-platform).
1. Invoke the cross-platform API by creating an instance of the partial class and invoking its methods as required. For more information, see [Invoke the cross-platform API](#invoke-the-cross-platform-api).

## Define the cross-platform API

To invoke platform code from cross-platform code, the first step is to define the cross-platform API as a [partial class](/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods#partial-classes) that defines [partial method](/dotnet/csharp/programming-guide/classes-and-structs/partial-classes-and-methods#partial-classes) signatures for any operations you want to invoke on each platform.

The following example shows a cross-platform API that can be used to retrieve the orientation of a device:

```csharp
namespace InvokePlatformCodeDemos.Services
{
public enum DeviceOrientation
{
Undefined,
Landscape,
Portrait
}

public partial class DeviceOrientationService
{
public partial DeviceOrientation GetOrientation();
}
}
```

The partial class is named `DeviceOrientationService`, which includes a partial method named `GetOrientation`.

## Implement the API per platform

After defining the cross-platform API, it must be implemented on your required platforms by defining the same partial class and the same partial method signatures, while also providing the method implementations.

Platform implementations should be placed in the correct _Platforms_ child folders to ensure that the build system only attempts to build platform code when building for the specific platform. The following table lists the default folder locations for platform implementations:

| Platform | Folder |
| -------- | ------ |
| Android | _Platforms_ > _Android_ |
| iOS | _Platforms_ > _iOS_ |
| MacCatalyst | _Platforms_ > _MacCatalyst_ |
| Windows | _Platforms_ > _Windows_ |

> [!IMPORTANT]
> Platform implementations must be in the same namespace and same class that the cross-platform API was defined in.

The following screenshot shows the `DeviceOrientationService` classes in the _Android_ and _iOS_ folders:

:::image type="content" source="media/invoke-platform-code/implement-api.png" alt-text="DeviceOrientationService classes in their Platforms folder screenshot.":::

Alternatively, multi-targeting can be performed based on your own filename and folder criteria, rather than using the _Platforms_ folders. For more information, see [Configure multi-targeting](#configure-multi-targeting).

### Android

The following example shows the implementation of the `GetOrientation` method on Android:

```csharp
using Android.Content;
using Android.Runtime;
using Android.Views;

namespace InvokePlatformCodeDemos.Services
{
public partial class DeviceOrientationService
{
public partial DeviceOrientation GetOrientation()
{
IWindowManager windowManager = Android.App.Application.Context.GetSystemService(Context.WindowService).JavaCast<IWindowManager>();
SurfaceOrientation orientation = windowManager.DefaultDisplay.Rotation;
bool isLandscape = orientation == SurfaceOrientation.Rotation90 || orientation == SurfaceOrientation.Rotation270;
return isLandscape ? DeviceOrientation.Landscape : DeviceOrientation.Portrait;
}
}
}
```

### iOS

The following example shows the implementation of the `GetOrientation` method on iOS:

```csharp
using UIKit;

namespace InvokePlatformCodeDemos.Services
{
public partial class DeviceOrientationService
{
public partial DeviceOrientation GetOrientation()
{
UIInterfaceOrientation orientation = UIApplication.SharedApplication.StatusBarOrientation;
bool isPortrait = orientation == UIInterfaceOrientation.Portrait || orientation == UIInterfaceOrientation.PortraitUpsideDown;
return isPortrait ? DeviceOrientation.Portrait : DeviceOrientation.Landscape;
}
}
}
```

## Invoke the cross-platform API

After providing the platform implementations, the API can be invoked from cross-platform code by creating an object instance and invoking its operation:

```csharp
using InvokePlatformCodeDemos.Services;
...

DeviceOrientationService deviceOrientationService = new DeviceOrientationService();
DeviceOrientation orientation = deviceOrientationService.GetOrientation();
```

At build time the build system will use multi-targeting to combine the cross-platform partial class with the partial class for the target platform, and build it into the app package.

## Configure multi-targeting

.NET MAUI apps can also be multi-targeted based on your own filename and folder criteria. This enables you to structure your .NET MAUI app project so that you don't have to place your platform code into child folders of the _Platforms_ folder.

For example, a standard multi-targeting pattern is to include the platform as an extension in the in the filename for the platform code. The build system can configured to combine cross-platform partial classes with platform partial classes based on this pattern:

:::image type="content" source="media/invoke-platform-code/multi-target-filenames.png" alt-text="DeviceOrientationService classes using filename-based multi-targeting.":::

Another standard multi-targeting pattern is to include the platform as a folder name. The build system can configured to combine cross-platform partial classes with platform partial classes based on this pattern:

:::image type="content" source="media/invoke-platform-code/multi-target-folders.png" alt-text="DeviceOrientationService classes using folder-based multi-targeting.":::

For more information, see [Configure multi-targeting](configure-multi-targeting.md).
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading