[Windows Phone 7.5] Supprimer le “pinch to zoom” sur un contrôle WebBrowser

Le ViewPort

Le ViewPort se défini dans le code HTML. Il indique la largeur “virtuelle” de la page web. Sur un terminal mobile, on a envie d’ajuster le ViewPort en fonction de la largeur de l’écran, et d’une plateforme à une autre, ça peut varier (ça sera la même pour tous les Windows Phone). Le ViewPort permet de définir plusieurs propriétés:

  • width: par défaut, 320 (pixels). Comme ça c’est compatible iPhone, et après c’est le navigateur qui se charge de faire la conversion “pixels web –> pixels réels”.
  • height : par défaut, 480
  • user-scalable: permet de définir si l’utilisateur peut zoomer dans la page

 

Certaines plateformes définissent des paramètres comme minimum-scale, maximum-scale, ou initial-scale… Ils ne sont pas supportées par IE9 dans Windows Phone.

Le truc classique en manipulant le viewport pour supprimer l’effet de zoom, c’est de passer le paramètre user-scalable à “no” et le paramètre “width” à “device-width”:

 <meta name="viewport" content="width=device-width, user-scalable=no"/>  

 

Supprimer les manipulations

Mais cela ne suffit pas! En effet, si l’utilisateur essaie de zoomer, la page zoomera quand même… puis reviendra en place automatiquement, empêchant d’afficher un autre niveau de zoom que celui prescrit initialement, mais indiquant à l’utilisateur que son geste a bien été pris en compte (bonne pratique d’ergonomie en général, mais pas top quand on veut cacher qu’on utilise une webview… parce qu’on sait tous que c’est pourri!).

Pour supprimer cet effet, il faut supprimer carrément les évènements de manipulation au niveau du contrôle WebBrowser. cela nécessite un peu de code qui m’a gentiment été soufflé par nos amis d’Ucaya, et plus particulièrement Romuald, dont l’origine est ce post de Colin Eberhardt:

 private void WebBrowser_Loaded(object sender, System.Windows.RoutedEventArgs e)
{
    var border = ((Microsoft.Phone.Controls.WebBrowser)sender).Descendants<Border>().Last() as Border;

    border.ManipulationDelta += Border_ManipulationDelta;
    border.ManipulationCompleted += Border_ManipulationCompleted;
}

private void Border_ManipulationCompleted(object sender,
                                    ManipulationCompletedEventArgs e)
{
    // suppress zoom
    if (e.FinalVelocities.ExpansionVelocity.X != 0.0 ||
        e.FinalVelocities.ExpansionVelocity.Y != 0.0)
        e.Handled = true;
}

private void Border_ManipulationDelta(object sender,
                                        ManipulationDeltaEventArgs e)
{
    // suppress zoom
    if (e.DeltaManipulation.Scale.X != 0.0 ||
        e.DeltaManipulation.Scale.Y != 0.0)
        e.Handled = true;

    //// optionally suppress scrolling
    //if (ScrollDisabled)
    //{
    //    if (e.DeltaManipulation.Translation.X != 0.0 ||
    //      e.DeltaManipulation.Translation.Y != 0.0)
    //        e.Handled = true;
    //}
}

Evidemment, il faut associer la méthode WebBrowser_Loaded à l’évènement Loaded du contrôle WebBrowser…

Petite précision à propos de ce bout de code: il utilise la très excellente extension LinqToVisualTree qu’il faudra donc ajouter également au projet…

Et voila, plus d’effet de zoom. Ceci étant dit, ça ne doit pas vous encourager à utiliser les WebBrowser pour autre chose qu’afficher des pages HTML… et surtout, quelqu’en soit votre utilisation, ne les utilisez jamais, AU GRAND JAMAIS, dans un Panorama ou un Pivot, ça casse l’expérience de navigation horizontale. Il y a une place spéciale en enfer pour les gens qui font ça. Vous voilà prévenu!

Du bon usage du contrôle WebBrowser

Les contrôles de type “WebBrowser”, (ou WebView) sont rarement bien utilisés…

Un WebBrowser, c’est fait pour afficher du contenu web (du HTML) parce qu’on ne veut/peut pas le parser (par exemple, une page d’authentification OAuth).

  • Ce n’est pas fait pour éviter d’avoir à créer une expérience native.
  • Ce n’est pas fait pour réutiliser des vues entre différentes plateformes.
  • Ce n’est pas fait pour s’acheter une place sur un store, qu’on n’aurait pas eu avec un site web mobile.

 

Malheureusement 90% du temps c’est ça qu’on voit. Il ne faut pas faire. Une expérience native c’est justement pour avoir quelque chose de spécifique à chaque plateforme, en terme d’ergonomie, de look’n’feel. C’est ce que les utilisateurs attendent! Malheureusement le développement d’application n’est pas toujours piloté par le développeur soucieux de la beauté du code, ou le créa soucieux de la beauté des visuels et des animations. Des fois, le responsable du projet qui n’a pas assez de sous, ou de temps, et qui doit faire avec ce qu’il a… et on se retrouve avec des webviews mal utilisées.

Alors quand on utilise un contrôle WebBrowser, pour de bonnes ou de mauvaises raisons, il faut en contrôler le comportement. Sinon on se retrouve sur wtfmobileweb.com.

Encore merci à @RomuxX pour l’info, et pour d’autres lectures intéressantes sur le sujet, je vous encourage à aller voir la page sur le développement web pour Windows Phone 7.5, sur MSDN.