XAML

9 articles

Image depuis HTTP avec C# XAML – Comparatifs et Performances – Partie 1

Introduction

Chargement Bitmap Image en Http

Voici un article en 2 parties pour décrire les différentes implémentations possibles de la lecture d’images provenant d’un serveur en Http.
En terme de performances, il existe des différences assez conséquentes suivant les implémentations choisies.

Nous allons voir que parfois les résultats sont assez surprenants.

Charger une image depuis XAML

Le moyen le plus simple pour charger une image reste l’implémentation XAML.

<Image Source="{Binding ImageUrl}" Width="400" Height="240"/>

ImageUrl est de type Url et peut être déclarée de cette façon dans le viewModel associé à la Page.

public  Uri ImageUrl
{
    get
    {
        return new Uri(@"http://www.bing.com/az/hprichbg/rb/SnowyCP_FR-FR11972876588_400x240.jpg");
    }
}

Cette implémentation est très efficace, le contrôle XAML gère quasiment tout pour vous :

  • le chargement en asynchrone : Ne fige pas l’affichage de l’interface lors du chargement
  • la mise en cache mémoire (un seul chargement)
  • L’optimisation http (évite un échange serveur si l’image est déjà chargée)

Cependant l’image chargée en XAML sera de nouveau rechargée à chaque lancement de l’application.
Afin de mettre en place un système de cache persisté, il est nécessaire de charger le contenu de l’image et de la sauvegarder sur le téléphone dans l’Isolated Storage.

Quelles sont les méthodes possibles pour charger et afficher une image en asynchrone ?

Voici 9 façons de faire en Universal Apps (Windows Phone XAML ou Windows 8.1). Leurs temps de réponse seront mesurés sur Windows Phone 8.1 et exposés dans la 2ème partie de cet article.

Implémentations

 

1 – DataWriter

La première implémentation, la plus classique, est d’utiliser un httpClient pour récupérer le flux sous forme de Stream puis de le transférer dans le BitmapImage en passant par un DataWritter.

Windows 8 et les Universal Apps nous obligent à passer par un nouveau type de Stream le InMemoryRandomAccessStream pour l’afficher comme source dans le BitmapImage. Poursuivre la lecture

Mise en cache d’image dans l’isolated storage avec Windows XAML et SemaphoreSlim

 

Ecriture dans l’isolated Storage d’un fichier image

Ecriture Multiple dans l'Isolated Storage

Il est parfois fort utile de sauvegarder les images provenant d’un serveur HTTP dans un cache afin d’éviter de les charger à chaque fois.

En implémentant ce système de cache en asynchrone, je me suis rendu compte de plusieurs problèmes causant systématiquement un UnauthorizedAccessException: Access is denied (0x80070005).

Poursuivre la lecture

Migration du LongListSelector en Universal Apps – 2ème Partie

Nous poursuivons l’article sur la migration du LongListSelector (WP8 et WP8.Silverlight) vers les Universal Apps (WP8 et W8.x)

Nous avons vu dans le précédent article la migration des listes simples et des listes regroupées.

Dans cet article nous allons voir maintenant la migration du « JumpList ».

Le JumpList permet d’offrir des raccourcis de navigation lors du clic (ou tap) sur un regroupement.

Migrer le Jumplist en Universal Apps - Liste regtroupée wp_ss_20140925_0004

Avant avec le LongListSelector

En WP8.0 Silverlight, la gestion du JumpList passe obligatoirement par la définition du style associé à la propriété JumpListStyle. Sans cette association, la Jumplist ne fonctionnait pas.

Poursuivre la lecture

Migration vers XAML 8.1 – les resw (migration rapide)

 

Cet article fait suite au précédent article concernant la migration de la partie « traduction » d’une application Windows Phone (7, 8 et Silverlight 8.1) en 8.1 XAML (Universal Apps)

Universal apps et traduction

Universal Apps

Nous avons pu voir précédemment que le portage pouvait être parfois un peu lourd.
Dans le cas où vous avez déjà de nombreuses ressources traduites dans les fichiers resx volumineux (et dans plusieurs langues), la suite peut vous intéresser.

Les identifiants de ressources

Nous avons vu dans le précédent article qu’il suffisait de

  1. renommer les fichiers .resx en .resw
  2. les mettre dans des répertoires normés avec un identifiant les ressources (ex : en-US, fr-FR,..)
  3. modifier le XAML pour remplacer le « {Binding… » par un x:Uid
  4. modifier tous les identifiants de ressources pour ajouter la propriété du contrôle qui sera traduite.

Pour éviter ce dernier cas parfois très lourd, il existe un solution qui peux vous faire gagner un peu de temps.

Poursuivre la lecture

Icones Segoe UI Symbol et C#

 

Les icônes Segoe UI Symbol

Microsoft depuis Windows 8 recommande d’utiliser des icônes provenant d’une police de caractères « Segoe UI Symbol ».

C’est très pratique, il suffit de choisir cette fonte et de connaître ensuite le code pour directement accéder à l’image vectorielle de très bonne qualité, et personnalisable avec de la couleur.

Certains caractères ont une largeur nulle permettant également de faire un contour d’une autre couleur ou encore de créer un cercle autour de l’cône.

Les palettes d’icônes Segoe UI Symbol sont consultables sur différents sites :

exemple :

 

SgoeUiSymbol

 

C’est assez simple, dans une application XAML, il suffit de codifier le caractère avec les tags XML standards.

Poursuivre la lecture

Pinch to Zoom avec Windows et Windows Phone 8.1

Comment rendre une image zoomable?

Pour l’application Infografx, j’ai eu besoin de gérer le zoom d’un graphique à travers un « pinch to zoom »

Zoom-Gesture

 

Lors de l’utilisation d’une image, l’utilisateur doit pouvoir zoomer et se déplacer dans le Zoom.

Mon premier réflex a été de coder l’utilisation de se zoom et du scale à partir des évenements de manipulation. Et puis comme j’étais dans un modèle M-V-VM j’ai même utilisé un behavior pour rendre le code plus propre.

Tout celà pour rien, car il existe une manière bien plus simple et bien plus efficace…

Avant

Avant, il fallait coder les gestes de l’utilisateur intervenant sur l’image.

Voici un exemple de code qui fait intervenir 2 évènements sur le contrôle ManipulationStart et ManipulationDelta.

    private void image_OnManipulationDelta(object sender, ManipulationDeltaEventArgs e)
    {
        var transform = (CompositeTransform)image.RenderTransform;

        // pan
        transform.TranslateX = _translationX + e.CumulativeManipulation.Translation.X;
        transform.TranslateY = _translationY + e.CumulativeManipulation.Translation.Y;

        // zoom
        if (e.PinchManipulation != null)
        {
            transform.CenterX = e.PinchManipulation.Original.Center.X;
            transform.CenterY = e.PinchManipulation.Original.Center.Y;

            transform.ScaleX = _scaleX * e.PinchManipulation.CumulativeScale;
            transform.ScaleY = _scaleY * e.PinchManipulation.CumulativeScale;
        }
    }

    private void image_OnManipulationStarted(object sender, ManipulationStartedEventArgs e)
    {
        // the user has started manipulating the screen, set starting points
        var transform = (CompositeTransform)image.RenderTransform;
        _scaleX = transform.ScaleX;
        _scaleY = transform.ScaleY;
        _translationX = transform.TranslateX;
        _translationY = transform.TranslateY;
    }

Le code est assez long, le résultat n’est pas parfait car un peu rigide (pas de gestion de l’inertie) et pas facile à insérer dans un modèle M-V-VM.

Il existe un moyen pourtant bien plus simple.

Le ScrollViewer

Avec Windows 8 et les projets Windows Phone 8.1 (non Silverlight), le scrollviewer est enrichi d’un Zoom.

En Initialisant la propriété ZoomMode avec « Enabled », vous bénéficiez d’un Pinch To Zoom sur n’importe quel contenu du ScrollViewer

D’autres propriétés permettent également de paramétrer votre zoom :

  • MinZoomFactor : Pour fixer le zoom minimum (exemple 0.25)
  • MaxZoomFactor : Pour fixer le zoom maximum (exemple 3.0)
  • IsZoomInertiaEnabled : Pour gérer l’inertie du zoom (exemple false)

Ce qui donne en XAML

 <ScrollViewer Width="Auto" Height="Auto" VerticalScrollBarVisibility="Visible"
                          HorizontalScrollBarVisibility="Visible" Margin="4"
                          ZoomMode="Enabled"                           
                          MinZoomFactor="0.25"
                          MaxZoomFactor="3.0"
                          IsZoomInertiaEnabled="False"
                          >
                <Grid VerticalAlignment="Top" HorizontalAlignment="Left"
                       >
...

 

Et voilà! En quelques lignes de code XAML le tour est joué. vous avez un zoom parfait, sans code à maintenir et 100% M-V-VM.

WPF, ListView d’images, MVVM et Drag and Drop… – Fin

Introduction

Les projets précédents ont été redécoupés afin de fournir 2 assemblies directement utilisable.

Pour ceux qui souhaitent ajouter rapidement un treeview d’images avec une gestion de Drag&Drop (Voir les 4 précédents chapitres ) voici les étapes de réalisation.

L’exemple suivant montre comment réaliser une application respectant l’architecture M-V-VM avec les briques Drag and Drop et Listview d’images

Application M-V-VM exemple avec Liste en arbre de type TreeView

Il vous faudra :

  1. Ajouter les assemblies
  2. Définir un objet possédant l’Interface IImageFile (et IParentItem si vous souhaiter des structures hiérarchiques)
  3. Définir un objet ViewModel dérivant de CustomImageFileViewModel si vous voulez gérer le DragAndDrop provenant d’applications externes
  4. Initialiser les images dans CollectionImageViewModel

Implémentation

Ajouts des assemblies

La première étape est de télécharger ou compiler les assemblies suivantes (à la fin de l’article) :

  • ImageFileListView : Contient la partie visuelle, le View Model et les interfaces du modèle à implémenter
  • DragDropManager : Contient les mécanismes de Drag and Drop qui pourront être appliqués sur la lise

Ajout de la liste dans la View

Pour ajouter la liste dans la View vous devez définir une référence dans le XAML à l’assemblie ImageFileListView.

xmlns:m="clr-namespace:ImageFileListView.View;assembly=ImageFileListView"

Poursuivre la lecture

WPF, ListView d’images, MVVM et Drag and Drop… – Partie 1

Introduction

Pour les besoins d’un logiciel orienté « Photos », j’ai eu besoin des fonctionnalités essentielles suivantes :

  • Affichage des images sous forme de vignettes dans une liste et dans une arborescence de type TreeView
  • Cet affichage doit permettre de gérer un nombre imposant de photos (>5000 !) sans générer de débordement mémoire ou de ralentissement
  • L’affichage et la génération des vignettes doit pouvoir se faire en mode asynchrone (en lisant les informations EXIF si elles existent,…)
  • La multi-sélection doit permettre de sélectionner plusieurs éléments.
  • Les éléments sélectionnés doivent pouvoir être déplacés ou copiés dans la liste (ou l’arbre) par Drag And Drop

Et le tout en DotNet WPF respectant le pattern MVVM !!!

MVVM Pattern

Je ne ferai pas un gros article sur la nécessité de développer en WPF selon une architecture MVVM (Séparation des fonctions, réutilisation, rôle des objets mieux ciblés, accès déclaratifs…). Voici quelques liens au cas où vous ne seriez toujours pas convaincus…

http://www.orbifold.net/default/?p=550
http://japf.developpez.com/tutoriels/dotnet/mvvm-pour-des-applications-wpf-bien-architecturees-et-testables/
http://msdn.microsoft.com/fr-fr/magazine/dd419663.aspx
http://www.c2i.fr/Article/Detail/a3809f7b-196a-4d8c-bb48-164f591920bb

MVVM et ListView

Cette première partie présente l’implémentation de la liste d’images avec le modèle MVVM.

Exemple d’application

Voici le descriptif fonctionnel de l’exemple que nous allons mettre en place : Un petit croquis vaut mieux qu’un long discours.

Draft MVVM application

L’application est extrêmement simpliste. La saisie d’un répertoire se fait en haut, le click sur le bouton affiche la liste des images et leur nombre total.

Découpage de l’application

L’application est découpée en 4 parties :

  • Model : l’objet “métier” image
  • ViewModel : les objets nécessaires à la manipulation des objets “Model” images par la couche “View” (Détail de l’image et liste des images)
  • View : L’affichage XAML-WPF de la liste des images
  • Controler : Les actions nécessaires : Remplissage de la liste par exemple

Poursuivre la lecture

Manipulations de matrices avec du code non sécurisé

La classe Matrix

Dans cet article nous allons comparer 2 méthodes qui traitent de multiplication de matrices en .Net | C#.

Nous commençons par la définition de la classe matrice :  Matrix

    class Matrix
    {
        private readonly double[,] _matrix;
        public Matrix(int dim1, int dim2)
        {
            _matrix = new double[dim1, dim2];
        }

        public int Height { get { return _matrix.GetLength(0); } }
        public int Width { get { return _matrix.GetLength(1); } }

        public double this[int x, int y]
        {
            get { return _matrix[x, y]; }
            set { _matrix[x, y] = value; }
        }
    }

Multiplications de matrices

Voici le premier algorithme de multiplication de matrice qui réalise l’opération de manière standard.

    public static Matrix NaiveMultiplication(Matrix m1, Matrix m2)
    {
        Matrix resultMatrix = new Matrix(m1.Height, m2.Width);
        for (int i = 0; i < resultMatrix.Height; i++)
        {
            for (int j = 0; j < resultMatrix.Width; j++)
            {
                resultMatrix[i, j] = 0;
                for (int k = 0; k < m1.Width; k++)
                {
                    resultMatrix[i, j] += m1[i, k] * m2[k, j];
                }
            }
        }
        return resultMatrix;
    }

Voici le second algorithme qui réalise la même chose, mais cette fois en utilisant du code non sécurisé (unsafe)

Poursuivre la lecture