ContentIsland

ContentIslandto interfejs API WinUI 3 i Zestaw SDK do aplikacji systemu Windows, który umożliwia hostowanie zawartości renderowania innej niż XAML, takich jak wizualizacje kompozycji, zawartość Win2D lub powierzchnie Direct3D, wewnątrz aplikacji WinUI 3. Każda wyspa to izolowana powierzchnia renderowania z własnym stanem wejścia, wyjścia, układu i dostępności. Wyspę podrzędną łączysz z miejscem na wyspie nadrzędnej za pomocą elementu ChildSiteLink.

Użyj elementu ContentIsland do obsługi zaawansowanych scenariuszy interoperacyjności, w których potrzebna jest treść, której nie można wyrazić za pomocą standardowych elementów XAML.

Note

ContentIsland jest przeznaczony dla zaawansowanych scenariuszy renderowania. W przypadku większości interfejsów użytkownika aplikacji należy użyć standardowych kontrolek XAML WinUI 3.

Jak działa contentIsland

Aplikacja XAML WinUI 3 działa już wewnątrz elementu ContentIsland. Możesz uzyskać wyspę nadrzędną z lokalizacji XamlRoot.ContentIsland. Aby umieścić dodatkową zawartość inną niż XAML w drzewie XAML, należy wykonać następujące czynności:

  1. Zarezerwuj miejsce w XAML.
  2. Utwórz podgląd umiejscowienia na wyspie nadrzędnej.
  3. Utwórz obiekt ChildSiteLink dla tej wizualizacji położenia.
  4. Utwórz element podrzędny ContentIsland z własną wizualizacją główną.
  5. Połącz wyspę podrzędną i utrzymuj jej rozmiar oraz przekształcenie zsynchronizowane z układem XAML.

Wyspa podrzędna może następnie hostować zawartość kompozycji, rysunek Win2D, wizualizacje oparte na direct3D lub inną zawartość renderowania inną niż XAML.

Rezerwowanie miejsca w XAML

Zacznij od kontenera głównego i elementu zastępczego, w którym pojawi się wyspa podrzędna.

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

Utwórz wyspę podrzędną

Utwórz wizualizację rozmieszczenia w wyspie nadrzędnej, a następnie utwórz i połącz wyspę podrzędną.

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 pobiera katalog główny Visual dla sceny wyspy. Po nawiązaniu połączenia z wyspą możesz dodać zawartość kompozycji w ramach tej wizualizacji głównej.

Położenie wyspy względem elementu XAML

Zachowaj wizualizację umieszczania i ChildSiteLink zsynchronizowaną z elementem zastępczym. Ten przykład odwzorowuje granice symbolu zastępczego do panelu głównego, a następnie aktualizuje zarówno wizualizację położenia, jak i łącze.

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

Synchronizowanie zmian układu

Subskrybuj zmiany układu, aby wyspa podrzędna pozostawała zgodna z symbolem zastępczym 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();
}

Jeśli animujesz element zastępczy lub zmieniasz jego rozmiar, wywołaj UpdateContentIslandLayout za każdym razem, gdy zmieniają się jego rzeczywisty rozmiar lub pozycja.

Dodawanie zawartości do wyspy podrzędnej

Po utworzeniu wyspy podrzędnej dodaj zawartość kompozycji w obszarze wizualizacji głównej podrzędnej.

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

Możesz zastąpić SpriteVisual własnym drzewem wizualnym opartym na Win2D lub Direct3D.

Czyszczenie wysp

ContentIsland i ChildSiteLink są zasobami, które można zamknąć. Zamknij lub zlikwiduj je, gdy nie są już potrzebne.

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

Obsłuż czyszczenie w elemencie Unloaded lub podczas zamykania okna, aby niezwłocznie zwolnić zasoby renderowania.

Aplikacja Galeria WinUI 3 zawiera interaktywne przykłady wielu kontrolek i funkcji platformy WinUI 3.