Exibição Web

Um controle de modo de exibição da Web incorpora uma exibição no seu aplicativo que renderiza o conteúdo da Web usando o mecanismo de renderização da Versão Prévia do Microsoft Edge. Hiperlinks também podem aparecer e funcionar em um controle de modo de exibição da Web.

Importante

O WebView2 controle está disponível como parte do Windows Biblioteca de Interface do Usuário 3 (WinUI3). WebView2usa Microsoft Edge (Chromium) como o mecanismo de renderização para exibir o conteúdo da Web em aplicativos. Para obter mais informações, consulte Introdução ao Microsoft Edge WebView2, Introdução ao WebView2 na WinUI 3 (versão prévia) e WebView2 na referência da API WinUI.

Esse é o controle correto?

Utilize um controle de modo de exibição na Web para exibir o conteúdo HTML sofisticadamente formatado de um servidor Web remoto, código gerado dinamicamente ou arquivos de conteúdo no pacote de seu aplicativo. Conteúdo sofisticado também pode conter código de script e comunicar-se entre o script e o código de seu aplicativo.

Recomendações

  • Certifique-se de que o site carregado está formatado corretamente para o dispositivo e utiliza cores, tipografia e navegação consistentes com o restante de seu aplicativo.
  • Os campos de entrada devem ser dimensionados adequadamente. Os usuários podem não perceber que é possível ampliá-los para inserir texto.
  • Se um modo de exibição na Web não se parecer com o resto de seu aplicativo, considere a possibilidade de utilizar controles ou meios alternativos para realizar tarefas relevantes. Se o modo de exibição na Web corresponder ao resto de seu aplicativo, os usuários o verão como uma experiência perfeita.

Criar um modo de exibição da Web

Modificar a aparência de um modo de exibição da Web

WebView não é uma subclasse de Control, portanto, não tem um modelo de controle. No entanto, você pode definir várias propriedades para controlar alguns aspectos visuais do modo de exibição da Web.

  • Para restringir a área de exibição, defina as propriedades Width e Height.
  • Para mover, dimensionar, inclinar e girar uma exibição da Web, use a propriedade RenderTransform.
  • Para controlar a opacidade do modo de exibição da Web, defina a propriedade Opacity.
  • Para especificar uma cor para usar como a tela de fundo da página da Web quando o conteúdo HTML não especificar uma cor, defina a propriedade DefaultBackgroundColor.

Obter o título da página da Web

Você pode obter o título do documento HTML exibido atualmente no modo de exibição da Web usando a propriedade DocumentTitle.

Ordem de tabulação e eventos de entrada

Embora o WebView não seja uma subclasse Control, ele receberá o foco de entrada do teclado e participar na sequência de tabulação. Ele fornece um método Focus, e eventos GotFocus e LostFocus, mas não tem nenhuma propriedade relacionada a guias. Sua posição na sequência de tabulação é a mesma que sua posição na ordem do documento de XAML. A sequência de tabulação inclui todos os elementos no conteúdo de modo de exibição da Web que pode receber o foco de entrada.

Conforme indicado na tabela Eventos na página da classe WebView, o modo de exibição da Web não dá suporte à maioria dos eventos de entrada de usuário herdados do UIElement, como KeyDown, KeyUp e PointerPressed. Em vez disso, você pode usar InvokeScriptAsync com a função eval do JavaScript para usar os manipuladores de eventos HTML e usar o window.external.notify do manipulador de eventos HTML para notificar o aplicativo usando WebView.ScriptNotify.

O modo de exibição da Web conta com várias APIs para navegação básica: GoBack, GoForward, Stop, Refresh, CanGoBack e CanGoForward. Você pode usá-los para adicionar recursos típicos de navegação na Web a seu aplicativo.

Para definir o conteúdo inicial do modo de exibição da Web, defina a propriedade Source no XAML. O analisador XAML converte automaticamente a cadeia de caracteres para um URI.

<!-- Source file is on the web. -->
<WebView x:Name="webView1" Source="http://www.contoso.com"/>

<!-- Source file is in local storage. -->
<WebView x:Name="webView2" Source="ms-appdata:///local/intro/welcome.html"/>

<!-- Source file is in the app package. -->
<WebView x:Name="webView3" Source="ms-appx-web:///help/about.html"/>

A propriedade Source pode ser definida no código, mas em vez de fazer isso, você normalmente usa um dos métodos Navigate para carregar conteúdo no código.

Para carregar o conteúdo da Web, use o método Navigate com um URI que usa o esquema http ou https.

webView1.Navigate(new Uri("http://www.contoso.com"));

Para navegar para o URI com uma solicitação POST e cabeçalhos HTTP, use o método NavigateWithHttpRequestMessage. Esse método dá suporte apenas a HttpMethod.Post e HttpMethod.Get para o valor da propriedade HttpRequestMessage.Method.

Para carregar o conteúdo descompactado e não criptografado do armazenamento de dados LocalFolder ou TemporaryFolder de seu aplicativo, use o método Navigate com um URI que usa o esquema ms-appdata. O suporte à exibição da Web para esse esquema requer que você coloque o conteúdo em uma subpasta sob a pasta local ou temporária. Isso permite a navegação para URIs como ms-appdata:///local/folder/file.html e ms-appdata:///temp/folder/file.html. (Para carregar arquivos compactados ou criptografados, confira NavigateToLocalStreamUri).

Cada uma dessas subpastas de primeiro nível é isolada do conteúdo em outras subpastas de primeiro nível. Por exemplo, você pode navegar para ms-appdata:///temp/folder1/file.html, mas não pode ter um link nesse arquivo para ms-appdata:///temp/folder2/file.html. No entanto, você ainda pode vincular ao conteúdo HTML no pacote do aplicativo usando o ms-appx-web scheme e ao conteúdo da Web usando os esquemas de URI http e https.

webView1.Navigate(new Uri("ms-appdata:///local/intro/welcome.html"));

Para carregar o conteúdo do pacote do aplicativo, use o método Navigate com um URI que usa o esquema ms-appx-web.

webView1.Navigate(new Uri("ms-appx-web:///help/about.html"));

Você pode carregar o conteúdo local por meio de uma resolução personalizada usando o método NavigateToLocalStreamUri. Isso possibilita cenários avançados, como download e armazenamento em cache de conteúdo baseado na Web para uso offline ou extração de conteúdo de um arquivo compactado.

Respondendo a eventos de navegação

O controle de modo de exibição da Web fornece vários eventos que você pode usar para responder a navegação e estados de carregamento de conteúdo. Os eventos ocorrem na seguinte ordem para o conteúdo de modo de exibição da Web raiz: NavigationStarting, ContentLoading, DOMContentLoaded, NavigationCompleted

NavigationStarting – ocorre antes do modo de exibição da Web navegar para um novo conteúdo. Você pode cancelar a navegação em um manipulador para esse evento, definindo a propriedade WebViewNavigationStartingEventArgs.Cancel como true.

webView1.NavigationStarting += webView1_NavigationStarting;

private void webView1_NavigationStarting(object sender, WebViewNavigationStartingEventArgs args)
{
    // Cancel navigation if URL is not allowed. (Implemetation of IsAllowedUri not shown.)
    if (!IsAllowedUri(args.Uri))
        args.Cancel = true;
}

ContentLoading – ocorre quando a exibição da Web começar a carregar um novo conteúdo.

webView1.ContentLoading += webView1_ContentLoading;

private void webView1_ContentLoading(WebView sender, WebViewContentLoadingEventArgs args)
{
    // Show status.
    if (args.Uri != null)
    {
        statusTextBlock.Text = "Loading content for " + args.Uri.ToString();
    }
}

DOMContentLoaded – ocorre quando o modo de exibição da Web tiver terminado de analisar o conteúdo HTML atual.

webView1.DOMContentLoaded += webView1_DOMContentLoaded;

private void webView1_DOMContentLoaded(WebView sender, WebViewDOMContentLoadedEventArgs args)
{
    // Show status.
    if (args.Uri != null)
    {
        statusTextBlock.Text = "Content for " + args.Uri.ToString() + " has finished loading";
    }
}

NavigationCompleted – ocorre quando o modo de exibição da Web tiver terminado de carregar o conteúdo atual ou se tiver ocorrido uma falha na navegação. Para determinar se a navegação falhou, verifique as propriedades IsSuccess e WebErrorStatus da classe WebViewNavigationCompletedEventArgs.

webView1.NavigationCompleted += webView1_NavigationCompleted;

private void webView1_NavigationCompleted(WebView sender, WebViewNavigationCompletedEventArgs args)
{
    if (args.IsSuccess == true)
    {
        statusTextBlock.Text = "Navigation to " + args.Uri.ToString() + " completed successfully.";
    }
    else
    {
        statusTextBlock.Text = "Navigation to: " + args.Uri.ToString() + 
                               " failed with error " + args.WebErrorStatus.ToString();
    }
}

Eventos semelhantes ocorrem na mesma ordem para cada iframe no conteúdo de modo de exibição da Web:

  • FrameNavigationStarting – Ocorre antes de um quadro no modo de exibição da Web navegar para um novo conteúdo.
  • FrameContentLoading – Ocorre quando um quadro no modo de exibição da Web começou a carregar um novo conteúdo.
  • FrameDOMContentLoaded – Ocorre quando um quadro no modo de exibição da Web concluiu a análise de seu conteúdo HTML atual.
  • FrameNavigationCompleted – Ocorre quando um quadro no modo de exibição da Web tiver terminado de carregar o conteúdo.

Respondendo a possíveis problemas

Você pode responder a possíveis problemas com o conteúdo, como execução prolongada de scripts, conteúdo que não pode carregar a exibição da Web e avisos de conteúdo não seguro.

Seu aplicativo pode parecer sem resposta durante a execução de scripts. O evento LongRunningScriptDetected ocorre periodicamente enquanto o modo de exibição da Web executa o JavaScript e oferece uma oportunidade para interromper o script. Para determinar por quanto tempo o script foi executado, verifique a propriedade ExecutionTime de WebViewLongRunningScriptDetectedEventArgs. Para interromper o script, defina a propriedade StopPageScriptExecution dos argumentos do evento como true. O script interrompido não será executado novamente, a menos que ele seja recarregado durante uma navegação de modo de exibição da Web subsequente.

O controle de modo de exibição da Web não pode hospedar tipos de arquivos arbitrários. Quando é feita uma tentativa de carregar o conteúdo que não pode hospedar o modo de exibição da Web, o evento UnviewableContentIdentified ocorre. Você pode manipular esse evento e notificar o usuário ou usar a classe Launcher para redirecionar o arquivo para um navegador externo ou de outro aplicativo.

Da mesma forma, o evento UnsupportedUriSchemeIdentified ocorre quando um esquema de URI que não tem suporte é chamado no conteúdo da Web, como o fbconnect:// ou mailto://. Você pode manipular esse evento para fornecer um comportamento personalizado em vez de permitir o iniciador de sistema padrão iniciar o URI.

O UnsafeContentWarningDisplayingevent ocorre quando o modo de exibição da Web mostra uma página de aviso para o conteúdo que foi relatado como inseguro pelo Filtro SmartScreen. Se o usuário optar por continuar a navegação, a navegação subsequente para a página não exibirá o aviso nem vai disparar o evento.

Manipulando casos especiais para exibir o conteúdo da Web

Você pode usar a propriedade ContainsFullScreenElement e o evento ContainsFullScreenElementChanged para detectar, responder e habilitar experiências de tela inteira no conteúdo da Web, por exemplo, na reprodução de vídeo em tela inteira. Por exemplo, você pode usar o evento ContainsFullScreenElementChanged para redimensionar o modo de exibição da Web para ocupar todo o modo de exibição do aplicativo ou, como o exemplo a seguir ilustra, colocar um aplicativo de janela no modo de tela inteira quando uma experiência de Internet em tela inteira é desejada.

// Assume webView is defined in XAML
webView.ContainsFullScreenElementChanged += webView_ContainsFullScreenElementChanged;

private void webView_ContainsFullScreenElementChanged(WebView sender, object args)
{
    var applicationView = ApplicationView.GetForCurrentView();

    if (sender.ContainsFullScreenElement)
    {
        applicationView.TryEnterFullScreenMode();
    }
    else if (applicationView.IsFullScreenMode)
    {
        applicationView.ExitFullScreenMode();
    }
}

Você pode usar o evento NewWindowRequested para tratar casos em que o conteúdo da Web hospedado solicita uma nova janela para ser exibido, como uma janela pop-up. Você pode usar outro controle WebView para exibir o conteúdo da janela solicitada.

Use o evento PermissionRequested para habilitar os recursos da Web que exigem recursos especiais. Atualmente, isso inclui localização geográfica, armazenamento IndexedDB e áudio e vídeo do usuário (por exemplo, de um microfone ou webcam). Se seu aplicativo acessar a localização ou mídia do usuário, você ainda precisará declarar essa funcionalidade no manifesto do aplicativo. Por exemplo, um aplicativo que usa a localização geográfica precisa no mínimo das seguintes declarações de funcionalidade no Package.appxmanifest:

  <Capabilities>
    <Capability Name="internetClient" />
    <DeviceCapability Name="location" />
  </Capabilities>

Além da manipulação do evento PermissionRequested pelo aplicativo, o usuário terá que aprovar caixas de diálogo do sistema padrão para aplicativos que solicitam recursos de mídia ou localização para que esses recursos sejam habilitados.

Aqui está um exemplo de como um aplicativo permitiria a localização geográfica em um mapa do Bing:

// Assume webView is defined in XAML
webView.PermissionRequested += webView_PermissionRequested;

private void webView_PermissionRequested(WebView sender, WebViewPermissionRequestedEventArgs args)
{
    if (args.PermissionRequest.PermissionType == WebViewPermissionType.Geolocation &&
        args.PermissionRequest.Uri.Host == "www.bing.com")
    {
        args.PermissionRequest.Allow();
    }
}

Se o aplicativo exigir entrada do usuário ou outras operações assíncronas para responder a uma solicitação de permissão, use o método Defer de WebViewPermissionRequest para criar um WebViewDeferredPermissionRequest que pode ser tratado em um momento posterior. Confira WebViewPermissionRequest.Defer.

Se os usuários precisarem sair com segurança de um site hospedado em um modo de exibição da Web ou em outros casos, quando a segurança é importante, chame o método estático ClearTemporaryWebDataAsync para apagar o todo o conteúdo armazenado em cache localmente em uma sessão de modo de exibição da Web. Isso impede que usuários mal-intencionados acessem dados confidenciais.

Interagindo com o conteúdo de modo de exibição da Web

Você pode interagir com o conteúdo do modo de exibição da Web usando o método InvokeScriptAsync para invocar ou inserir scripts no conteúdo de modo de exibição da Web e o evento ScriptNotify para obter informações de volta do conteúdo de modo de exibição da Web.

Para invocar o JavaScript dentro do conteúdo de modo de exibição da Web, use o método InvokeScriptAsync. O script chamado pode retornar apenas os valores de cadeia de caracteres.

Por exemplo, se o conteúdo de um modo de exibição da Web chamado webView1 contiver uma função denominada setDate que aceita 3 parâmetros, você poderá chamá-lo assim.

string[] args = {"January", "1", "2000"};
string returnValue = await webView1.InvokeScriptAsync("setDate", args);

Você pode usar o InvokeScriptAsync com a função do JavaScript eval para inserir conteúdo na página da Web.

Aqui, o texto de uma caixa de texto XAML (nameTextBox.Text) é gravado em um div em uma página HTML hospedada em webView1.

private async void Button_Click(object sender, RoutedEventArgs e)
{
    string functionString = String.Format("document.getElementById('nameDiv').innerText = 'Hello, {0}';", nameTextBox.Text);
    await webView1.InvokeScriptAsync("eval", new string[] { functionString });
}

Scripts no conteúdo de modo de exibição da Web podem usar window.external.notify com um parâmetro de cadeia de caracteres para enviar informações de volta para seu aplicativo. Para receber essas mensagens, manipule o evento ScriptNotify.

Para que uma página da Web externa possa acionar o evento ScriptNotify ao chamar window.external.notify, inclua o URI da página na seção ApplicationContentUriRules do manifesto do aplicativo. (Você pode fazer isso no Microsoft Visual Studio na guia URIs de Conteúdo do Package.appxmanifest designer). Os URIs dessa lista devem usar HTTPS e podem conter curingas de subdomínio (por exemplo, https://*.microsoft.com), mas não podem conter curingas de domínio (por exemplo, https://*.com e https://*.*). O requisito de manifesto não se aplica ao conteúdo que se origina no pacote do aplicativo, que usa um URI ms-local-stream:// ou que seja carregado usando o método NavigateToString.

Acessando o Windows Runtime em um modo de exibição da Web

Você pode usar o método AddWebAllowedObject para injetar uma instância de uma classe nativa de um componente do Windows Runtime no contexto do JavaScript do modo de exibição da Web. Isso permite acesso completo aos métodos, propriedades e eventos nativos desse objeto no conteúdo JavaScript desse modo de exibição da Web. A classe deve ser decorada com o atributo AllowForWeb.

Por exemplo, este código insere uma instância do MyClass importado de um componente do Windows Runtime em um modo de exibição da Web.

private void webView_NavigationStarting(WebView sender, WebViewNavigationStartingEventArgs args) 
{ 
    if (args.Uri.Host == "www.contoso.com")  
    { 
        webView.AddWebAllowedObject("nativeObject", new MyClass()); 
    } 
}

Para obter mais informações, confira WebView.AddWebAllowedObject.

Além disso, o conteúdo confiável do JavaScript em um modo de exibição da Web pode ter permissão para acessar diretamente as APIs do Windows Runtime. Isso proporciona poderosas capacidades nativas para aplicativos Web hospedados em um modo de exibição da Web. Para habilitar esse recurso, o URI do conteúdo confiável precisa estar na lista de permissões e no ApplicationContentUriRules do aplicativo em Package.appxmanifest, com WindowsRuntimeAccess especificamente definido para "all".

Este exemplo mostra uma seção do manifesto do aplicativo. Aqui, um URI local recebe acesso ao Windows Runtime.

  <Applications>
    <Application Id="App"
      ...

      <uap:ApplicationContentUriRules>
        <uap:Rule Match="ms-appx-web:///Web/App.html" WindowsRuntimeAccess="all" Type="include"/>
      </uap:ApplicationContentUriRules>
    </Application>
  </Applications>

Opções de hospedagem do conteúdo da Web

Você pode usar a propriedade WebView.Settings (do tipo WebViewSettings) para controlar se o JavaScript e IndexedDB estão habilitados. Por exemplo, se você usar um modo de exibição da Web para exibir conteúdo estritamente estático, convém desabilitar o JavaScript para obter melhor desempenho.

Captura de conteúdo do modo de exibição da Web

Para habilitar o compartilhamento de conteúdo do modo de exibição da Web com outros aplicativos, use o método CaptureSelectedContentToDataPackageAsync, que retorna o conteúdo selecionado como um DataPackage. Esse método é assíncrono, então você deve usar um adiamento para impedir que seu manipulador de evento DataRequested retorne antes da chamada assíncrona ser concluída.

Para obter uma imagem de visualização do conteúdo atual do modo de exibição da Web, use o método CapturePreviewToStreamAsync. Esse método cria uma imagem do conteúdo atual e grava o fluxo especificado.

Comportamento de threading

Por padrão, o conteúdo de modo de exibição da Web é hospedado no thread da IU em dispositivos na família de dispositivos da área de trabalho e fora do thread da IU em todos os outros dispositivos. Você pode usar a propriedade estática WebView.DefaultExecutionMode para consultar o comportamento de threading padrão para o cliente atual. Se necessário, você pode usar o construtor WebView(WebViewExecutionMode) para substituir esse comportamento.

Nota Pode haver problemas de desempenho ao hospedar conteúdo no thread da interface do usuário em dispositivos móveis, portanto, certifique-se de testar em todos os dispositivos de destino quando você alterar DefaultExecutionMode.

Um modo de exibição da Web que hospeda o conteúdo fora do thread de interface do usuário não é compatível com o controle dos pais que exigem gestos para propagar do controle de modo de exibição da Web ao pai, como FlipView, ScrollViewer e outros controles relacionados. Esses controles não poderão receber gestos iniciados no modo de exibição da Web fora do thread. Além disso, a impressão de conteúdo da Web fora do thread não tem suporte diretamente. Você deve imprimir um elemento com o WebViewBrush preenchido.

Obter o código de exemplo