Matez le WebView

Si vous vous êtes intéressé au développement pour le Windows Store et que vous envisagiez d’utiliser le WebView (control XAML) vous n’avez pas pu passer à côté des préconisations suivantes :

  • N’utilisez pas le WebView.
  • Le contenu affiché dans le WebView ne doit pas rompre avec le design de votre application.
  • Le comportement par défaut du WebView doit être inhibé (aucune navigation ne doit être possible).
  • … etc …

Malheureusement, la documentation ne dit pas comment se passer du WebView et endors moins comment respecter ces règles L

Pire, le control ne dispose pas de propriétés en rapport avec ces préconisations.

Ayant moi-même eu besoin d’utiliser ce control pour l’une de mes applications, j’ai trouvé le moyen de respecter ces règles en codant une attached property (MVVM oblige). Ma logique pour réaliser celle-ci a été simple : vu que le control ne peut pas être maitrisé finement, je vais maitriser le contenu que je lui donne à afficher.

Mes objectifs ont donc été simples :

  • Fournir à mon contenu un style HTML en rapport avec mon application (fond clair avec texte foncé écrit en Segoe)
  • Inhiber les liens HTML (je remplace les références aux url par une chaine vide)

Afin d’obtenir ce résultat, j’ai réalisé le code suivant :

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;

namespace MyLib.Common
{
    public sealed class WebViewUtility
    {
        #region Déclarations

        // Pattern utilisé pour trouver les url à subsituer
        private const String _pattern = @"(href=""[^""]+"")|(href='[^']+')|(href=[^ >]+)";
        private const String BindableSourcePropertyName = "BindableSource";
        
        // code HTML pour respecter le style de mon applcication
        private const String HtmlBeforeContent = @"<html><body style='background-color:#FFFFFF;color:#1D1D1D;height:100%;font-family:Segoe UI Symbol;margin:0;padding:0;'>";
        private const String HtmlAfterContent = @"</body></html>";

        private static readonly Regex _regex;
        public static readonly DependencyProperty BindableSourceProperty;

        #endregion

        #region Constructeur

        static WebViewUtility()
        {
            // DependencyProperty
            BindableSourceProperty = DependencyProperty.RegisterAttached(
                BindableSourcePropertyName, 
                typeof(String), 
                typeof(WebViewUtility),
                new PropertyMetadata(null, BindableSourcePropertyChanged));

            // Regex pour le replamcement des liens
            _regex = new Regex(_pattern,RegexOptions.CultureInvariant | RegexOptions.IgnoreCase);
        }

        #endregion

        #region DependencyProperty

        public static string GetBindableSource(DependencyObject obj)
        {
            return (string)obj.GetValue(BindableSourceProperty);
        }

        public static void SetBindableSource(DependencyObject obj, string value)
        {
            obj.SetValue(BindableSourceProperty, value);
        }

        public static void BindableSourcePropertyChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
        {
            WebView browser = o as WebView;
            if (browser != null)
            {
                // Remplacer les liens
                String content = e.NewValue as string;
                if (content == null) return;
                content = _regex.Replace(content, String.Empty);

                // Construction de code à afficher
                StringBuilder sb = new StringBuilder();
                sb.Append(HtmlBeforeContent);
                sb.Append(content);
                sb.Append(HtmlAfterContent);

                browser.NavigateToString(sb.ToString());
            }
        }
        #endregion
    }
}

Côté XAML, pour utiliser ce code, j’ai simplement

<Page
    x:Class="MyReader.WinRt.Common.CustomWebView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:MyReader.WinRt.Common"
    xmlns:mylib="using:MyLib.Common">    
    <Grid>
        <WebView
            x:Name="WebView"
            mylib:WebViewUtility.BindableSource="{Binding}"/>
        <Rectangle x:Name="Rect" Fill="Transparent"/>
    </Grid>
</Page>

Voilà, il ne vous reste plus qu’à modifier le Binding ne fonction de vos besoins ;)

Je confirme que ce code permet la validation de vos applications pour le Store, l’une de mes applications utile ce code et est aujourd’hui certifiée et publiée sur le Store

MyReader (https://www.microsoft.com/fr-fr/p/myreader/9wzdncrdkx3n?rtc=1)

Jérémy Jeanson

Comments

You have to be logged in to comment this post.