ContentIsland

ContentIslandest une API WinUI 3 et SDK d'application Windows qui vous permet d’héberger du contenu de rendu non XAML, tel que des visuels de composition, du contenu Win2D ou des surfaces Direct3D, à l’intérieur d’une application WinUI 3. Chaque île est une surface de rendu isolée avec son propre état d’entrée, de sortie, de disposition et d’accessibilité. Vous connectez une île enfant à un endroit dans l’île parente à l’aide d’un ChildSiteLink.

Utilisez ContentIsland pour les scénarios d’interopérabilité avancés où vous avez besoin de contenu qui n’est pas représenté sous forme d’éléments XAML standard.

Note

ContentIsland est destiné aux scénarios de rendu avancés. Pour la plupart de l’interface utilisateur de l’application, utilisez des contrôles XAML WinUI 3 standard.

Fonctionnement de ContentIsland

Une application XAML WinUI 3 s’exécute déjà à l’intérieur d’un ContentIsland. Vous pouvez obtenir cette île parent à partir de XamlRoot.ContentIsland. Pour placer du contenu non XAML supplémentaire dans l’arborescence XAML, vous devez :

  1. Réservez de l’espace en XAML.
  2. Créez un repère visuel de placement dans l’île parente.
  3. Créez un ChildSiteLink pour ce visuel d’emplacement.
  4. Créez un ContentIsland enfant avec son propre visuel racine.
  5. Connectez l’île enfant et conservez sa taille et sa transformation synchronisées avec la disposition XAML.

L’île enfant peut ensuite héberger le contenu de composition, le dessin Win2D, les visuels soutenus par Direct3D ou d’autres contenus de rendu non XAML.

Réserver de l’espace en XAML

Commencez par un conteneur racine et un élément d’espace réservé à l’emplacement où l’îlot enfant apparaîtra.

<Grid x:Name="RootPanel">
    <Border x:Name="IslandHost"
            Width="320"
            Height="200"
            HorizontalAlignment="Left"
            VerticalAlignment="Top" />
</Grid>

Créer une île enfant

Créez un visuel de placement dans l’île parente, puis créez et connectez l’île enfant.

using System.Numerics;
using Microsoft.UI.Composition;
using Microsoft.UI.Content;
using Microsoft.UI.Xaml;
using Microsoft.UI.Xaml.Hosting;

private ChildSiteLink? _childSiteLink;
private ContentIsland? _childIsland;
private ContainerVisual? _placementVisual;
private ContainerVisual? _childRootVisual;

private void CreateContentIsland()
{
    ContentIsland parentIsland = IslandHost.XamlRoot.ContentIsland;
    Compositor compositor = ElementCompositionPreview.GetElementVisual(RootPanel).Compositor;

    // This visual marks where the child island appears inside the parent island.
    _placementVisual = compositor.CreateContainerVisual();
    ElementCompositionPreview.SetElementChildVisual(RootPanel, _placementVisual);

    _childSiteLink = ChildSiteLink.Create(parentIsland, _placementVisual);

    // Create the root visual for the child island's own scene graph.
    _childRootVisual = compositor.CreateContainerVisual();
    _childIsland = ContentIsland.Create(_childRootVisual);

    _childSiteLink.Connect(_childIsland);

    UpdateContentIslandLayout();
}

ContentIsland.Create utilise l'élément racine Visual pour la scène de l’îlot. Une fois l’îlot connecté, vous pouvez ajouter du contenu Composition sous cet élément visuel racine.

Positionner l’île par rapport à un élément XAML

Conservez le visuel de placement et le ChildSiteLink synchronisé avec l’élément d’espace réservé. Cet exemple mappe les limites de l’espace réservé dans le panneau racine, puis met à jour à la fois l’élément visuel de placement et la liaison.

using System.Numerics;
using Windows.Foundation;

private void UpdateContentIslandLayout()
{
    if (_placementVisual is null || _childSiteLink is null)
    {
        return;
    }

    GeneralTransform transform = IslandHost.TransformToVisual(RootPanel);
    Point position = transform.TransformPoint(new Point(0, 0));

    Vector2 size = new((float)IslandHost.ActualWidth, (float)IslandHost.ActualHeight);
    Vector3 offset = new((float)position.X, (float)position.Y, 0);

    _placementVisual.Offset = offset;
    _placementVisual.Size = size;

    _childSiteLink.ActualSize = size;
    _childSiteLink.LocalToParentTransformMatrix =
        Matrix4x4.CreateTranslation(offset);
}

Synchroniser les modifications de disposition

Abonnez-vous aux modifications de disposition afin que l’îlot enfant reste aligné avec l’espace réservé XAML.

public MainPage()
{
    this.InitializeComponent();

    // XamlRoot is null until the element is in the visual tree.
    // Defer ContentIsland creation to the Loaded event.
    IslandHost.Loaded += OnIslandHostLoaded;
    IslandHost.LayoutUpdated += OnIslandHostLayoutUpdated;
    IslandHost.Unloaded += OnIslandHostUnloaded;
}

private void OnIslandHostLoaded(object sender, RoutedEventArgs e)
{
    IslandHost.Loaded -= OnIslandHostLoaded;
    CreateContentIsland();
}

private void OnIslandHostLayoutUpdated(object sender, object e)
{
    UpdateContentIslandLayout();
}

Si vous animez ou redimensionnez l’espace réservé, appelez UpdateContentIslandLayout chaque fois que sa taille ou sa position effective change.

Ajouter du contenu à l’île enfant

Après avoir créé l’îlot enfant, ajoutez du contenu Composition sous l’élément visuel racine enfant.

private void AddSpriteVisual()
{
    if (_childRootVisual is null)
    {
        return;
    }

    Compositor compositor = _childRootVisual.Compositor;

    SpriteVisual sprite = compositor.CreateSpriteVisual();
    sprite.Size = new Vector2(320, 200);
    sprite.Brush = compositor.CreateColorBrush(Microsoft.UI.Colors.DodgerBlue);

    _childRootVisual.Children.InsertAtTop(sprite);
}

Vous pouvez remplacer le SpriteVisual par votre propre arborescence visuelle basée sur Win2D ou Direct3D.

Nettoyer les îles

ContentIsland et ChildSiteLink sont des ressources pouvant être fermées. Fermez ou supprimez-les quand ils ne sont plus nécessaires.

private void OnIslandHostUnloaded(object sender, RoutedEventArgs e)
{
    IslandHost.LayoutUpdated -= OnIslandHostLayoutUpdated;
    IslandHost.Unloaded -= OnIslandHostUnloaded;

    _childIsland?.Close();
    _childSiteLink?.Close();

    _childIsland = null;
    _childSiteLink = null;
    _placementVisual = null;
    _childRootVisual = null;
}

Gérez le nettoyage dans Unloaded ou pendant l’arrêt de la fenêtre afin de libérer les ressources de rendu rapidement.

L’application Galerie WinUI 3 inclut des exemples interactifs de nombreux contrôles Et fonctionnalités de plateforme WinUI 3.