ContentIsland

ContentIsland je rozhraní API WinUI 3 a Windows App SDK, které umožňuje hostovat obsah vykreslovaný bez použití XAML, například vizuály Composition, obsah Win2D nebo plochy Direct3D, v aplikaci WinUI 3. Každý ostrov je izolovaný vykreslovací povrch s vlastním vstupem, výstupem, rozložením a stavem přístupnosti. Podřízený ostrov připojíte k místu v nadřazeném ostrově pomocí ChildSiteLink.

Používá se ContentIsland pro pokročilé scénáře spolupráce, ve kterých potřebujete obsah, který není vyjádřen jako standardní elementy XAML.

Note

ContentIsland je určený pro pokročilé scénáře vykreslování. Pro většinu uživatelského rozhraní aplikace použijte standardní ovládací prvky WinUI 3 XAML.

Jak contentIsland funguje

Aplikace WinUI 3 XAML už běží v rámci ContentIsland. Tento nadřazený ostrov můžete získat z XamlRoot.ContentIsland. Pokud chcete do stromu XAML umístit další obsah, který není XAML, provedete následující akce:

  1. Vyhraďte si místo v XAML.
  2. Vytvořte vizuál umístění v nadřazeném ostrůvku.
  3. Vytvořte pro toto umístění ChildSiteLink vizualizaci.
  4. Vytvoření podřízeného objektu ContentIsland s vlastním kořenovým vizuálem
  5. Připojte podřízený ostrov a udržujte jeho velikost a transformace synchronizované s rozvržením XAML.

Podřízený island pak může obsahovat obsah rozhraní Composition, kresbu Win2D, vizuály založené na Direct3D nebo jiný obsah vykreslovaný mimo XAML.

Rezervace místa v XAML

Začněte kořenovým kontejnerem a zástupným prvkem, kde se zobrazí podřízený ostrov.

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

Vytvořte podřízený ostrov

Vytvořte v nadřazeném ostrůvku vizuální prvek umístění a potom vytvořte a propojte podřízený ostrůvek.

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 představuje kořen Visual pro scénu ostrova. Po připojení islandu můžete pod tento kořenový vizuál přidat obsah kompozice.

Umístění ostrůvku vzhledem k elementu XAML

Ponechte vizuál umístění a ChildSiteLink synchronizovaný se zástupným prvkem. Tento příklad převede ohraničení zástupného symbolu do kořenového panelu a poté aktualizuje vizuální prvek umístění i odkaz.

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);
}

Synchronizace změn rozložení

Sledujte změny rozložení, aby podřízený prvek island zůstal zarovnaný se zástupným prvkem 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();
}

Pokud animujete nebo změníte velikost zástupného symbolu, zavolejte UpdateContentIslandLayout pokaždé, když se změní jeho efektivní velikost nebo umístění.

Přidejte obsah do podřízeného ostrůvku

Po vytvoření podřízeného islandu přidejte obsah Composition pod kořenový vizuál podřízeného islandu.

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);
}

SpriteVisual můžete nahradit vlastním stromem vizuálů založeným na Win2D nebo Direct3D.

Vyčištění ostrovů

ContentIsland a ChildSiteLink jsou uzavíratelné zdroje. Zavřete je nebo odstraňte, když už je nepotřebujete.

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;
}

Zpracujte vyčištění v Unloaded nebo při zavírání okna, aby se prostředky vykreslování uvolnily včas.

Aplikace Galerie WinUI 3 obsahuje interaktivní příklady mnoha ovládacích prvků WinUI 3 a funkcí platformy.