ContentIsland

ContentIslandé uma API do WinUI 3 e do SDK de Aplicações Windows que permite alojar conteúdos de renderização não XAML, como visuais de Composição, conteúdos Win2D ou superfícies Direct3D, dentro de uma aplicação WinUI 3. Cada ilha é uma superfície de renderização isolada com o seu próprio estado de entrada, saída, layout e acessibilidade. Liga uma ilha filha a um local na ilha-mãe usando um ChildSiteLink.

Use ContentIsland para cenários avançados de interoperabilidade onde 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 das interfaces de aplicações, usa controlos XAML padrão do WinUI 3.

Como funciona o ContentIsland

Uma aplicação XAML do WinUI 3 já é executada no interior de um ContentIsland. Podes obter essa ilha-mãe a partir de XamlRoot.ContentIsland. Para inserir conteúdo adicional que não seja XAML dentro da árvore XAML, deve:

  1. Reservar espaço em XAML.
  2. Crie um elemento visual de posicionamento na ilha-mãe.
  3. Crie uma ChildSiteLink para essa representação visual do posicionamento.
  4. Cria uma criança ContentIsland com a sua própria raiz visual.
  5. Ligue a ilha filha e mantenha o seu tamanho e transformação sincronizados com o layout XAML.

A ilha filha pode então alojar conteúdo de Composição, desenho Win2D, visuais suportados por Direct3D ou outro conteúdo de renderização não XAML.

Reservar espaço em XAML

Comece com um contentor raiz e um elemento provisório onde a ilha filha vai aparecer.

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

Criar uma ilha criança

Cria um visual de colocação na ilha principal e depois cria e liga 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 enraíza Visual a cena da ilha. Depois de a ilha estar ligada, podes adicionar conteúdo de Composição sob esse visual raiz.

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

Mantenha o posicionamento visual e o ChildSiteLink sincronizados com o elemento de marcador de posição. Este exemplo mapeia os limites do marcador de posição para o painel raiz e, em seguida, atualiza tanto o elemento visual de posicionamento como a ligação.

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

Subscreva as alterações de layout para que a ilha filha permaneça alinhada com o marcador 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 animar ou redimensionar o marcador de posição, chame UpdateContentIslandLayout sempre que o respetivo tamanho ou posição efetiva mudar.

Adicionar conteúdo à ilha criança

Depois de criares a ilha filha, adiciona conteúdo de Composição sob a raiz visual 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);
}

Podes substituir o SpriteVisual pela tua própria árvore visual suportada por Win2D ou Direct3D.

Limpar ilhas

ContentIsland e ChildSiteLink são recursos que podem ser encerrados. Feche-os ou descarte-os quando já não forem 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;
}

Efetue a limpeza em Unloaded ou durante o encerramento da janela, de modo a libertar prontamente os recursos de renderização.

A aplicação WinUI 3 Gallery inclui exemplos interativos de muitos controlos e funcionalidades da plataforma do WinUI 3.