Navegador web con el control WebView en C# (3)

Navegador web usando la versión moderna del control WebBrowser, el control WebView, que renderiza las páginas usando el motor de Microsoft Edge en lugar de hacerlo con el motor de Internet Explorer, añadiendo un segundo formulario que muestra el código HTML de la página que se visita, en C#

En 2 ejercicios anteriores (1 y 2) se desarrolla una aplicación de formularios de Windows con Visual Basic, construida alrededor de un objeto de la clase WebBrowser que permite mostrar en su interior páginas web y también interactuar con las páginas visitadas. Se trata de una clase muy madura que apareció en NET Framework 2, fácil de utilizar y con muchos textos de ayuda en Internet.
Pero tiene el inconveniente de que, por su antigüedad, utiliza el motor de renderizado de Internet Explorer, navegador actualmente obsoleto incluso para la propia Microsoft. En teoría renderiza con la versión de Internet Explorer que tengamos instalada en el sistema pero en la práctica parece mostrar las características de Internet Explorer 7 salvo que se manipule el registro para forzar a nuestra aplicación a utilizar el motor de la versión más moderna que es la 11 a condición de que la tengamos instalada (las instrucciones para hacerlo están en el artículo 2 de los referidos al principio del texto).

Microsoft ha desarrollado una clase que hereda bastantes de las características de WebBrowser pero renderizando con el motor de Microsoft Edge y con funcionalidades que la configuran como una clase más adaptada al entorno actual de Internet. Se trata de la clase WebView que no viene por defecto en Visual Studio 2017 pero se instala desde el paquete Microsoft.Toolkit.Win32.UI.Controls. Se requiere tener instalada la versión de desarrollo 4.6.2 o superior de NET. Framework, en caso contrario el paquete rehúsa la instalación.
El inconveniente que he encontrado es que existe todavía poca información para C# y menos para Visual Basic y que algunas de las propiedades, métodos y eventos de WebBroser, que en este control eran muy sencillos de implementar, no existen en WebView o son elementos diferentes de mayor complejidad.
WebView se puede usar en aplicaciones de tipo WPF (Windows Presentation Foundation) y, aunque ofrece más funcionalidad en aplicaciones modernas desarrolladas en XAML, con algunas limitaciones también se puede utilizar en aplicaciones con formularios Windows.

Nota: WebBrowser usa el motor de Microsoft Edge en Windows 10, en versiones anteriores de Windows recurre al motor de Internet Explorer.

He desarrollado una aplicación muy sencilla en C# cuya única finalidad es mostrar la manera de incluir WebView en un formulario Windows. El código ni siquiera tiene control de errores. Los métodos utilizados, que ya existían en el control anterior, son GoBack, GoForward, Navigate, Stop y Refresh. Además he utilizado métodos que detectan el inicio y la finalización de la carga de la página y he configurado otro formulario para mostrar el código HTML.

//Métodos de WebView: Navigate("url"), GoBack(), GoForward(), Stop() y Refresh()

private void Form1_Load(object sender, EventArgs e)
{
    webView1.Navigate("https://www.google.es/");
}

private void AtrásToolStripMenuItem_Click(object sender, EventArgs e)
{
    webView1.GoBack();
}

private void AdelanteToolStripMenuItem_Click(object sender, EventArgs e)
{
    webView1.GoForward();
}

private void PararLaCargaDeLaPáginaToolStripMenuItem_Click(object sender, EventArgs e)
{
    webView1.Stop();
}

private void RecargarLaPáginaToolStripMenuItem_Click(object sender, EventArgs e)
{
    webView1.Refresh();
}

En este ejercicio se emplean 2 métodos que detectan cuándo empieza la navegación hacia una página nueva (NavigationStarting) y cuándo ha terminado la carga de la página (NavigationCompleted). Sirven para colocar en un control TextBox la URL del sitio que se visita haciendo las funciones de barra de direcciones.

//Método que se ejecuta al comenzar la navegación a contenido nuevo
private void WebView1_NavigationStarting(object sender, WebViewControlNavigationStartingEventArgs e)
{
    //mostrar la URL de la página que se visita en el TextBox
    var sitio = e.Uri.ToString();
    textUrl.Text = sitio;
}

//Método que se ejecuta al terminar la navegación a contenido nuevo
private  void WebView1_NavigationCompleted(object sender, WebViewControlNavigationCompletedEventArgs e)
{
    //mostrar la URL de la página que se visita en el TextBox
    var sitio = e.Uri.ToString();
    textUrl.Text = sitio;           
}

Para que estos 2 métodos funcionen han de estar implementados en el archivo de diseño (Form1.Designer.cs) como es habitual en C#. El problema que he encontrado es que WebView presenta algunos fallos en Visual Studio 2017 y también en 2019, el más evidente es un cierre inesperado de la aplicación cuando se accede a su página de eventos en el diseñador de Windows Forms y se pulsa sobre alguno de los eventos que se desea configurar. Esto hace que haya que generar a mano tanto los métodos desencadenados por los eventos como sus manejadores y, cada vez que se realiza algún cambio en el diseñador, este regenera la región «Código generado por el Diseñador de Windows Forms» en Form1.Designer.cs y borra los 2 manejadores por lo que han de volver a escribirse.

this.webView1.NavigationStarting += this.WebView1_NavigationStarting;
this.webView1.NavigationCompleted += this.WebView1_NavigationCompleted;  

También se ha creado un botón que abre un segundo formulario con un control RichTextBox que muestra el código HTML de la página que se está visitando. Para pasar esta información entre los 2 formularios:
– en Form1 una variable string recibe el código HTML mediante JavaScript utilizando el método asincrónico InvokeScriptAsync que ha de ser declarado como async
– en Form2 se crea una propiedad pública a la que en Form1 se le asigna el valor de su variable string antes de mostrar Form2.
WebView no dispone de métodos propios para obtener el código HTML de la página visitada y por ello se utiliza JavaScript.

//En Form1
//abrir el formulario con el código fuente HTML de la página que se visita
private async void CodeHTMLToolStripMenuItem_ClickAsync(object sender, EventArgs e)
{
	//obtener el código HTML de la página con JavaScript, WebView no tiene métodos propios para ello
	string html = await webView1.InvokeScriptAsync("eval", new string[] { "document.documentElement.outerHTML;" });
	//declarar instancia del otro formulario y asignar la cadena html a su propiedad Texto
	Form2 f2 = new Form2
	{
		Texto = html
	};
	//mostrar Form2
	f2.ShowDialog();
}

//En Form2
//propiedad pública que se declara en Form2 pero en Form1 se asigna su valor antes de mostrar Form2
public string Texto { get; set; }
private void Form2_Load(object sender, EventArgs e)
{
    //rellenar el RichTextBox con el valor obtenido desde Form1
    this.RichTextBox1.Text = this.Texto;
}

Puedes descargar un archivo ZIP con la aplicación C# .

También puedes consultar las referencias básicas del control WebView como parte del espacio Windos.UI.Xaml.Controls en este artículo de Microsoft.

Deja un comentario

Tu dirección de correo electrónico no será publicada.