Visualizzazione Web

Un controllo visualizzazione Web integra nella tua app una visualizzazione che esegue il rendering di contenuto Web tramite il motore di rendering di legacy di Microsoft Edge. In un controllo visualizzazione Web possono anche apparire collegamenti ipertestuali funzionanti.

Importante

Il controllo WebView2 è disponibile come parte di WinUI3. WebView2 usa Microsoft Edge (Chromium) come motore di rendering per visualizzare il contenuto Web nelle app. Per altre informazioni, vedere Introduzione a Microsoft Edge WebView2, Attività iniziali per WebView2 in WinUI 3 (anteprima) e WebView2 nelle informazioni di riferimento sulle API WinUI.

È il controllo giusto?

Usa un controllo visualizzazione Web per visualizzare contenuto HTML con formattazione complessa da un server Web remoto, codice generato in modo dinamico o file di contenuto nel pacchetto dell'app. Il contenuto complesso può anche includere codice script e stabilire una comunicazione tra lo script e il codice dell'app.

Consigli

  • Assicurati che il sito Web caricato sia formattato correttamente per il dispositivo e che usi colori, caratteri tipografici ed esplorazione coerenti con il resto dell'app.
  • I campi di input devono avere dimensioni appropriate. Gli utenti potrebbero non rendersi conto di poter ingrandire la visualizzazione per immettere testo.
  • Se l'aspetto di una visualizzazione Web non è coerente con il resto dell'app, prendi in considerazione controlli o modi alternativi per eseguire le attività correlate. Se la visualizzazione Web è uniforme con il resto dell'app, potrai offrire agli utenti un'esperienza unificata coerente.

Creare una visualizzazione Web

Modificare l'aspetto di una visualizzazione Web

WebView non è una sottoclasse di Control, quindi non ha un modello di controllo. Puoi comunque impostare varie proprietà per controllare alcuni aspetti visivi della visualizzazione Web.

  • Per limitare l'area di visualizzazione, imposta le proprietà Width e Height.
  • Per traslare, ridimensionare, inclinare e ruotare una visualizzazione Web, usa la proprietà RenderTransform.
  • Per controllare l'opacità della visualizzazione Web, imposta la proprietà Opacity.
  • Per specificare un colore da usare come sfondo della pagina Web quando il contenuto HTML non specifica un colore, imposta la proprietà DefaultBackgroundColor.

Ottenere il titolo della pagina Web

Puoi ottenere il titolo del documento HTML attualmente visualizzato nella visualizzazione Web usando la proprietà DocumentTitle.

Eventi di input e ordine di tabulazione

Sebbene WebView non sia una sottoclasse di Control, riceve lo stato attivo di input dalla tastiera e partecipa alla sequenza di tabulazione. Include un metodo Focus e gli eventi GotFocus e LostFocus, ma non ha alcuna proprietà correlata all'ordine di tabulazione. La sua posizione nella sequenza di tabulazione è la stessa che occupa nell'ordine del documento XAML. La sequenza di tabulazione include tutti gli elementi nel contenuto della visualizzazione Web che possono ricevere lo stato attivo.

Come indicato nella tabella Eventi della pagina della classe WebView, la visualizzazione Web non supporta la maggior parte degli eventi di input utente ereditati da UIElement, come KeyDown, KeyUp e PointerPressed. In alternativa, puoi usare InvokeScriptAsync con la funzione JavaScript eval per usare i gestori di eventi HTML e usare window.external.notify dal gestore eventi HTML per inviare notifiche all'applicazione tramite WebView.Scriptnotify.

La visualizzazione Web offre diverse API per la navigazione di base: GoBack, GoForward, Stop, Refresh, CanGoBack e CanGoForward. Puoi usare questi elementi per aggiungere funzionalità tipiche dell'esplorazione Web alla tua app.

Per impostare il contenuto iniziale della visualizzazione Web, imposta la proprietà Source in XAML. Il parser XAML converte automaticamente la stringa in un 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"/>

La proprietà Source può essere impostata nel codice, ma piuttosto che procedere in questo modo, in genere si usa uno dei metodi Navigate per caricare il contenuto nel codice.

Per caricare contenuto Web, usa il metodo Navigate con un Uri che usa lo schema http o https.

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

Per passare a un URI con una richiesta POST e intestazioni HTTP, usa il metodo NavigateWithHttpRequestMessage. Questo metodo supporta solo HttpMethod.Post e HttpMethod.Get per il valore della proprietà HttpRequestMessage.Method.

Per caricare contenuto non compresso e non crittografato dagli archivi dati LocalFolder o TemporaryFolder della tua app, usa il metodo Navigate con un Uri che usa lo schema ms-appdata. Il supporto di questo schema per la visualizzazione Web richiede l'inserimento del contenuto in una sottocartella della cartella locale o temporanea. Questo consente il passaggio a URI come ms-appdata:///local/cartella/file.html e ms-appdata:///temp/cartella/file.html . Per caricare file compressi o crittografati, vedi NavigateToLocalStreamUri.

Ognuna di queste sottocartelle di primo livello è isolata dal contenuto nelle altre sottocartelle di primo livello. Ad esempio, puoi passare a ms-appdata:///temp/cartella1/file.html, ma non puoi avere un collegamento a ms-appdata:///temp/cartella2/file.html in questo file. Puoi comunque collegarti a contenuti HTML nel pacchetto dell'app con lo schema ms-appx-web e a contenuti Web con gli schemi URI http e https.

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

Per caricare il contenuto dal pacchetto dell'app, usa il metodo Navigate con un Uri che usa lo schema ms-appx-web.

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

Puoi caricare contenuto locale tramite un resolver personalizzato con il metodo NavigateToLocalStreamUri. Sono così possibili scenari avanzati come il download e la memorizzazione nella cache di contenuto basato su Web per l'uso offline o l'estrazione di contenuto da un file compresso.

Risposta agli eventi di spostamento

Il controllo visualizzazione Web include vari eventi che puoi usare per rispondere agli stati di spostamento o di caricamento del contenuto. Gli eventi si verificano nell'ordine seguente per il contenuto della visualizzazione Web radice: NavigationStarting, ContentLoading, DOMContentLoaded, NavigationCompleted

NavigationStarting - Si verifica prima dello spostamento della visualizzazione Web su nuovo contenuto. Puoi annullare lo spostamento in un gestore per questo evento impostando la proprietà WebViewNavigationStartingEventArgs.Cancel su true.

webView1.NavigationStarting += webView1_NavigationStarting;

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

ContentLoading - Si verifica quando la visualizzazione Web inizia a caricare nuovo contenuto.

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 - Si verifica quando la visualizzazione Web completa l'analisi del contenuto HTML corrente.

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 - Si verifica quando la visualizzazione Web completa il caricamento del contenuto corrente o in caso di esito negativo dello spostamento. Per determinare se lo spostamento non è riuscito, controlla le proprietà IsSuccess e WebErrorStatus della 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();
    }
}

Si verificano eventi simili nello stesso ordine per ogni iframe del contenuto della visualizzazione Web:

  • FrameNavigationStarting - Si verifica prima dello spostamento di un frame nella visualizzazione Web su nuovo contenuto.
  • FrameContentLoading - Si verifica quando un frame nella visualizzazione Web inizia a caricare nuovo contenuto.
  • FrameDOMContentLoaded - Si verifica quando viene completata l'analisi del contenuto HTML corrente di un frame nella visualizzazione Web.
  • FrameNavigationCompleted - Si verifica quando viene completato il caricamento del contenuto in un frame nella visualizzazione Web.

Risposta ai potenziali problemi

Puoi rispondere a potenziali problemi relativi al contenuto, ad esempio script a esecuzione prolungata, contenuto non caricabile nella visualizzazione Web e avvisi di contenuto non sicuro.

L'app potrebbe sembrare bloccata durante l'esecuzione degli script. L'evento LongRunningScriptDetected viene generato periodicamente durante l'esecuzione di JavaScript nella visualizzazione Web e offre la possibilità di interrompere lo script. Per determinare la durata dell'esecuzione dello script, controlla la proprietà ExecutionTime di WebViewLongRunningScriptDetectedEventArgs. Per interrompere lo script, imposta la proprietà StopPageScriptExecution degli argomenti dell'evento su true. Lo script arrestato non verrà eseguito nuovamente, a meno che non venga ricaricato durante uno spostamento successivo nella visualizzazione Web.

Il controllo visualizzazione Web non può ospitare tipi di file arbitrari. Quando viene eseguito un tentativo di caricare contenuto che la visualizzazione Web non può ospitare, si verifica l'evento UnviewableContentIdentified. Puoi gestire questo evento e inviare notifica all'utente o usare la classe Launcher per reindirizzare il file in un browser esterno o un'altra app.

Analogamente, l'evento UnsupportedUriSchemeIdentified si verifica quando viene richiamato uno schema URI non supportato nel contenuto Web, ad esempio fbconnect:// o mailto://. Puoi gestire questo evento per fornire un comportamento personalizzato invece di consentire l'avvio dell'URI dalla funzione di avvio del sistema predefinita.

L'evento UnsafeContentWarningDisplaying si verifica quando la visualizzazione Web mostra una pagina di avviso per il contenuto segnalato come non sicuro dal filtro SmartScreen. Se l'utente sceglie di continuare lo spostamento, per gli spostamenti successivi nella pagina non verrà visualizzato il messaggio e non verrà generato l'evento.

Gestione di casi speciali per il contenuto della visualizzazione Web

Puoi usare la proprietà ContainsFullScreenElement e l'evento ContainsFullScreenElementChanged per rilevare, rispondere e abilitare esperienze a schermo intero nel contenuto Web, ad esempio la riproduzione di video a schermo intero. Ad esempio, potresti usare l'evento ContainsFullScreenElementChanged per ridimensionare la visualizzazione Web in modo da occupare l'intera visualizzazione dell'app o, come illustrato nell'esempio seguente, attivare la modalità a schermo intero per un'app in modalità a finestra quando è richiesta un'esperienza Web a schermo intero.

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

Puoi usare l'evento NewWindowRequested per gestire i casi in cui il contenuto Web ospitato richiede una nuova finestra per essere visualizzato, ad esempio una finestra popup. Puoi usare un altro controllo WebView per visualizzare il contenuto della finestra richiesta.

Usa l'evento PermissionRequested per abilitare le funzionalità Web che richiedono funzionalità speciali, tra cui attualmente la georilevazione, l'archiviazione IndexedDB e audio e video dell'utente (ad esempio, da un microfono o una webcam). Se la tua app accede alla posizione o ad elementi multimediali dell'utente, è comunque necessario dichiarare questa funzionalità nel manifesto dell'app. Ad esempio, un'app che usa la georilevazione richiede come minimo le seguenti dichiarazioni di funzionalità in Package.appxmanifest:

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

Oltre al fatto che l'app deve gestire l'evento PermissionRequested, l'utente dovrà approvare le finestre di dialogo di sistema standard per le app che richiedono la posizione o funzionalità multimediali, per consentire l'abilitazione di queste funzionalità.

Ecco un esempio di come abilitare la georilevazione in una mappa di Bing in un'app:

// 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 l'app richiede l'input dell'utente o altre operazioni asincrone per rispondere a una richiesta di autorizzazione, usa il metodo Defer di WebViewPermissionRequest per creare una WebViewDeferredPermissionRequest su cui è possibile intervenire in seguito. Vedi WebViewPermissionRequest.Defer.

Se gli utenti devono disconnettersi in modo sicuro da un sito Web ospitato in una visualizzazione Web o in altri casi in cui la sicurezza è importante, chiama il metodo statico ClearTemporaryWebDataAsync per cancellare tutto il contenuto memorizzato nella cache in locale da una sessione della visualizzazione Web. In questo modo si impedisce l'accesso a dati sensibili da parte di utenti malintenzionati.

Interazione con il contenuto della visualizzazione Web

Puoi interagire con il contenuto della visualizzazione Web usando il metodo InvokeScriptAsync per richiamare o inserire script all'interno del contenuto della visualizzazione Web e l'evento ScriptNotify per ottenere le informazioni restituite dal contenuto della visualizzazione Web.

Per richiamare JavaScript all'interno del contenuto della visualizzazione Web, usa il metodo InvokeScriptAsync. Lo script richiamato può restituire solo valori stringa.

Ad esempio, se il contenuto di una visualizzazione Web denominata webView1 contiene una funzione denominata setDate che accetta 3 parametri, puoi richiamarla come segue.

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

Puoi usare InvokeScriptAsync con la funzione JavaScript eval per inserire contenuto nella pagina Web.

In questo esempio, il testo di una casella di testo XAML (nameTextBox.Text) viene scritto in elemento div in una pagina HTML ospitata in 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 });
}

Gli script nel contenuto della visualizzazione Web possono usare window.external.notify con un parametro stringa per restituire informazioni alla tua app. Per ricevere questi messaggi, dovrai gestire l'evento ScriptNotify.

Per consentire a una pagina Web esterna di generare l'evento ScriptNotify per la chiamata a window.external.notify, devi includere l'URI della pagina nella sezione ApplicationContentUriRules del manifesto dell'app. (Questa operazione può essere eseguita in Microsoft Visual Studio nella scheda URI del contenuto della finestra di progettazione Package.appxmanifest). Gli URI in questo elenco devono usare HTTPS e possono contenere caratteri jolly di sottodominio (ad esempio, https://*.microsoft.com) ma non possono contenere caratteri jolly di dominio (ad esempio, https://*.com e https://*.*). Il requisito per il manifesto non si applica al contenuto che proviene dal pacchetto dell'app, usa un URI ms-local-stream:// oppure viene caricato tramite NavigateToString.

Accesso a Windows Runtime in una visualizzazione Web

Puoi usare il metodo AddWebAllowedObject per inserire un'istanza di una classe nativa da un componente Windows Runtime nel contesto JavaScript della visualizzazione Web. Ciò consente l'accesso completo ai metodi, alle proprietà e agli eventi nativi di tale oggetto nel contenuto JavaScript della visualizzazione Web. La classe deve essere decorata con l'attributo AllowForWeb.

Ad esempio, questo codice inserisce un'istanza di MyClass importata da un componente Windows Runtime in una visualizzazione Web.

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

Per altre informazioni, vedi WebView.AddWebAllowedObject.

Inoltre, è possibile consentire al contenuto JavaScript attendibile in una visualizzazione Web di accedere direttamente alle API Windows Runtime. In questo modo diventano disponibili potenti funzionalità native per le app Web ospitate in una visualizzazione Web. Per abilitare questa funzionalità, l'URI per il contenuto attendibile deve essere inserito nell'elenco degli elementi consentiti in ApplicationContentUriRules dell'app nel file Package.appxmanifest, con WindowsRuntimeAccess impostato in modo specifico su "all".

Questo esempio mostra una sezione del manifesto dell'app. In questo caso viene concesso l'accesso a Windows Runtime a un URI locale.

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

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

Opzioni per l'hosting di contenuto Web

Puoi usare la proprietà WebView.Settings (di tipo WebViewSettings) per stabilire se JavaScript e IndexedDB sono abilitati. Ad esempio, se usi una visualizzazione Web per visualizzare contenuto strettamente statico, potrebbe essere utile disabilitare JavaScript per ottenere prestazioni ottimali.

Acquisizione del contenuto della visualizzazione Web

Per consentire la condivisione del contenuto della visualizzazione Web con altre app, usa il metodo CaptureSelectedContentToDataPackageAsync, che restituisce il contenuto selezionato come DataPackage. Questo metodo è asincrono, pertanto devi usare un differimento per impedire al gestore dell'evento DataRequested di restituire il controllo prima del completamento della chiamata asincrona.

Per ottenere un'immagine di anteprima del contenuto corrente della visualizzazione Web, usa il metodo CapturePreviewToStreamAsync. Questo metodo crea un'immagine del contenuto corrente e la scrive nel flusso specificato.

Comportamento di threading

Per impostazione predefinita, il contenuto della visualizzazione Web è ospitato nel thread dell'interfaccia utente nei dispositivi nella famiglia desktop e fuori dal thread dell'interfaccia utente in tutti gli altri dispositivi. Puoi usare la proprietà statica WebView.DefaultExecutionMode per richiedere il comportamento di threading predefinito per il client corrente. Se necessario, puoi usare il costruttore WebView(WebViewExecutionMode) per eseguire l'override di questo comportamento.

Nota Potrebbero verificarsi problemi di prestazioni in caso di hosting del contenuto nel thread dell'interfaccia utente nei dispositivi mobili, quindi assicurarsi di eseguire test in tutti i dispositivi di destinazione quando si cambia DefaultExecutionMode.

Una visualizzazione Web che ospita contenuto fuori dal thread dell'interfaccia utente non è compatibile con i controlli padre che richiedono la propagazione dei movimenti dal controllo visualizzazione Web al controllo padre, ad esempio i controlli FlipView, ScrollViewer e altri controlli correlati. Questi controlli non potranno ricevere i movimenti eseguiti nella visualizzazione Web al di fuori del thread. Inoltre, la stampa di contenuto Web al di fuori del thread non è supportata direttamente. Dovresti invece stampare un elemento con il riempimento WebViewBrush.

Scaricare il codice di esempio