ContentIsland

ContentIslandé uma API winui 3 e SDK do Aplicativo Windows que permite hospedar conteúdo de renderização não XAML, como visuais de composição, conteúdo Win2D ou superfícies Direct3D, dentro de um aplicativo WinUI 3. Cada ilha é uma superfície de renderização isolada com seu próprio estado de entrada, saída, layout e acessibilidade. Você conecta uma ilha filha a um local na ilha pai usando um ChildSiteLink.

Use ContentIsland para cenários avançados de interoperabilidade em que você precisa de conteúdo que não seja expresso como elementos XAML padrão.

Note

ContentIsland destina-se a cenários avançados de renderização. Para a maioria da interface do usuário do aplicativo, use controles XAML padrão do WinUI 3.

Como o ContentIsland funciona

Um aplicativo XAML do WinUI 3 já é executado dentro de um ContentIsland. Você pode obter essa ilha principal a partir de XamlRoot.ContentIsland. Para colocar conteúdo adicional não XAML dentro da árvore XAML, você:

  1. Reserve espaço em XAML.
  2. Crie um elemento visual de posicionamento na ilha principal.
  3. Crie um ChildSiteLink para esse elemento visual de posicionamento.
  4. Crie uma ContentIsland filha com seu próprio visual raiz.
  5. Conecte a ilha filha e mantenha seu tamanho e transformação sincronizados com o layout XAML.

A ilha filha pode então hospedar conteúdo de composição, desenhos com Win2D, visuais baseados em Direct3D ou outro conteúdo de renderização que não seja XAML.

Reservar espaço em XAML

Comece com um contêiner raiz e um elemento marcador onde a ilha filha aparecerá.

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

Criar uma ilha filha

Crie um visual de posicionamento na ilha pai e, em seguida, crie e conecte a ilha filha.

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 recebe o Visual raiz da cena da ilha. Depois que a ilha estiver conectada, você poderá adicionar conteúdo do Composition sob esse visual raiz.

Posicionar a ilha em relação a um elemento XAML

Mantenha o posicionamento visual e o ChildSiteLink sincronizados com o elemento placeholder. Este exemplo mapeia os limites do espaço reservado no painel raiz e, em seguida, atualiza o visual de posicionamento e o link.

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

Sincronizar alterações de layout

Inscreva-se para receber notificações de alterações de layout para que a ilha filha permaneça alinhada com o espaço reservado 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();
}

Se você animar ou redimensionar o espaço reservado, chame UpdateContentIslandLayout sempre que seu tamanho ou posição efetiva mudar.

Adicionar conteúdo à ilha filha

Depois de criar a ilha filha, adicione conteúdo de composição sob o visual raiz da ilha filha.

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

Você pode substituir o SpriteVisual pela sua própria árvore visual baseada em Win2D ou Direct3D.

Limpar ilhas

ContentIsland e ChildSiteLink são recursos que podem ser fechados. Feche ou descarte-os quando eles não forem mais necessários.

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

Lide com a limpeza em Unloaded ou durante o fechamento da janela para liberar os recursos de renderização prontamente.

O aplicativo da Galeria do WinUI 3 inclui exemplos interativos de muitos controles WinUI 3 e recursos de plataforma.