IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Dvp.NET Discussion :

Sortie de la version 0.5 de Dvp.NET


Sujet :

Dvp.NET

  1. #1
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut Sortie de la version 0.5 de Dvp.NET
    La version 0.5 de la librairie Dvp.NET est disponible !



    Pour installer Dvp.NET, le plus simple est d'utiliser Nuget, le gestionnaire de packages pour Visual Studio, comme expliqué ici. Vous pouvez aussi télécharger la librairie directement en utilisant les liens à la fin de ce post.

    Encore une fois, de nombreuses nouveautés sont au programme de cette version. Et comme d'habitude, c'est un peu hétéroclite : il y en a pour tous les goûts ou presque... voici la liste des nouveautés :

    • Assembly Developpez.Dotnet :
      • Classe StreamExtensions :
        • Méthode d’extension Tee : duplique ce qu'on écrit sur un flux vers un autre flux (ou plusieurs). Similaire à la commande UNIX tee
      • Classe TextWriterExtensions :
        • Méthode d’extension Tee : comme StreamExtensions.Tee, mais pour les TextWriter. Exemple :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          6
              // Copie dans le log tout ce qu'on écrit sur la console
              using(var logFile = new StreamWriter("log.txt", true))
              using (var output = Console.Out.Tee(logFile))
              {
                  output.WriteLine("Hello");
              }
      • Classe EnumerableExtensions :
        • Méthodes d’extension MinBy/MaxBy/Min(IComparer)/Max(IComparer) : correction d'un bug dans le cas d'une séquence vide (ça renvoyait la valeur par défaut alors qu'il fallait lever une exception, comme pour les méthodes Min/Max standards de Linq)
        • Méthodes d’extension AllMaxBy/AllMinBy : comme MaxBy/MinBy, mais renvoie tous les éléments qui ont la valeur max/min (au lieu d'un seul)
        • Méthode d'extension ElementDefaultValue : permet d'obtenir la valeur par défaut du type d'élément d'une collection (utile quand on travaille avec des types anonymes)
        • Méthode d’extension TakeLast : optimisation du cas où la collection implémente IList<TSource>
        • Méthode d’extension AggregateByPairs : comme Aggregate, mais prend les éléments de la liste 2 par 2. Exemple d'application : on a un itinéraire sous forme d’une liste de villes étapes, et une fonction qui renvoie la distance entre 2 villes. Pour avoir la distance totale, on peut faire ça :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          var totalDistance = cities.AggregateByPairs(0, (sum, a, b) => sum + Distance(a, b))
        • Méthode d’extension SequenceEqualBy : comme SequenceEqual, mais permet de spécifier le critère d'égalité :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          // Comparaison des listes selon l'id des éléments:
          if (list1.SequenceEqualBy(list2, x => x.Id))
          {
              ...
          }
        • Méthode d’extension Replace : remplace l'élément spécifié de la séquence par un autre :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          list.Replace("foo", "bar");
        • Méthodes d’extension InsertBefore/InsertAfter : insère un élément dans une séquence avant ou après chaque occurrence de l'élément spécifié :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          var input = new[] { "foo", "baz", "bar", "baz" };
          var result = input.InsertAfter("baz", "zoo");
          // result = { "foo", "baz", "zoo", "bar", "baz", "zoo" }
        • Méthodes d'extension InsertBeforeFirst/InsertAfterFirst : insère un élément dans une séquence avant ou après la première occurrence de l'élément spécifié :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          var input = new[] { "foo", "baz", "bar", "baz" };
          var result = input.InsertAfterFirst("baz", "zoo");
          // result = { "foo", "baz", "zoo", "bar", "baz" }
        • Méthodes d'extension RankBy/RankByDescending : associe à chaque élément son rang selon la clé spécifiée (comme RANK en SQL, bien que ça s'utilise pas tout à fait pareil). Le code suivant :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          6
          7
          8
          9
          var hallOfFame =
              players.RankByDescending(
                      p => p.Score,
                      (p, rank) => { Player = p, Rank = rank });
           
          foreach(var x in hallOfFame)
          {
              Console.WriteLine("{0}t{1}t{2}", x.Rank, x.Player.Name, x.Player.Score);
          }
          Produit la sortie suivante :
          1   William 100 
          2   Cheeta  50 
          3   Joe     42 
          3   Averell 42 
          3   Jane    42 
          6   Jack    25 
          6   Flipper 25 
          8   Tarzan  1
        • Méthodes d'extension DenseRankBy/DenseRankByDescending : idem, mais sans trous dans le classement (comme DENSE_RANK en SQL). Le code précédent avec DenseRankByDescending produit la sortie suivante :
          1   William 100 
          2   Cheeta  50 
          3   Joe     42 
          3   Averell 42 
          3   Jane    42 
          4   Jack    25 
          4   Flipper 25 
          5   Tarzan  1
        • Méthodes d’extension LeftOuterJoin/RightOuterJoin/FullOuterJoin : permettent d’effectuer plus facilement des jointures externes, qui ne sont pas très intuitives avec les opérateurs standards de Linq. Exemple :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          6
              var result =
                  list1.LeftOuterJoin(
                      list2,
                      x1 => x1.Id,
                      x2 => x2.Id,
                      (x1, x2) => new { x1, x2 });

      • Classe DateTimeExtensions :
        • Méthode d’extension Truncate : tronque une date au composant spécifié (année, mois, jour, heure, minute, seconde, milliseconde). Exemple :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          var firstDayOfMonth = DateTime.Now.Truncate(DateTimeComponent.Month)
        • Méthode StartOfWeek : renvoie la date de début de la semaine spécifiée (année et numéro de semaine) (cf. demande #1405).
      • Classe StringExtensions :
        • Méthodes d’extension From/To : correction d’un bug : si la chaine spécifiée dans le To n'était pas trouvée, ça renvoyait une chaine vide, au lieu de renvoyer toute la fin de la chaine.
        • Méthode d’extension Truncate : tronque une chaine de caractères à la longueur spécifiée.
      • Classe ReflectionExtensions :
        • Méthodes d'extension SetValue pour PropertyInfo et FieldInfo. Les méthodes "standard" PropertyInfo.SetValue et FieldInfo.SetValue ne fonctionnent pas avec les types valeurs, à cause du boxing. Ces nouvelles méthodes d'extension sont génériques (pour éviter le boxing) et prennent l'instance par référence (pour qu'on modifie bien l'objet d'origine et non une copie). On peut aussi les utiliser avec des types référence, histoire de pas avoir à se poser la question...
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          MyStruct obj = new MyStruct();
          typeof(MyStruct).GetProperty("Foo").SetValue(ref obj, 42);
      • Classe EncodingExtensions :
        • Méthode d’extension TryGetString : Tente de décoder une chaine de caractères à partir d'un tableau d'octets pour un encodage donné. Renvoie false si des données non valides pour cet encodage sont détectées :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          string text;
          if (!Encoding.UTF8.TryGetString(bytes, out text))
              Console.WriteLine("Données non valides");
        • Méthode d’extension IsValid : Vérifie si un tableau d'octets contient des données valides pour un encodage donné.
      • Classe CoreExtensions :
        • Méthode d'extension PreserveStackTrace : prépare une exception pour la relancer sans perdre la pile d'origine. Normalement, quand on relance dans un catch, il suffit de faire throw;, mais dans certains cas on ne peut pas faire ça (par exemple si on veut relancer la InnerException de l'exception interceptée). Exemple :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          6
          7
          8
              try
              {	        
                  Foo();
              }
              catch (TargetInvocationException ex)
              {
                  throw ex.InnerException.PreserveStackTrace();
              }
      • Classe NumberConverter (conversion de nombres en toutes lettres) :
        • Comme promis lors de la sortie de la version précédente : conversion de nombres en anglais (US et GB) !
          • La langue est choisie automatiquement en fonction de la culture courante si vous utilisez la classe NumberConverter, mais il est possible d’obtenir un convertisseur pour une culture spécifique avec la méthode GetSpeller.
          • Il est possible d’implémenter des convertisseurs pour d’autres langues en implémentant l’interface INumberSpeller
      • Classe OrderedDictionary<TKey, TValue> : un dictionnaire qui maintient l'ordre d'insertion des clés (comme System.Collections.Specialized.OrderedDictionary, mais en générique)
      • Classe XmlDumper : une sorte de sérialiseur XML simplifié, qui permet de convertir à peu près n’importe quel objet en XML. Ça peut être utile pour générer facilement du XML avec une structure libre à partir d’un objet anonyme, par exemple :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        var toto = new
        {
            Foo = 42,
            Bar = "Hello world",
            Baz = new { X = 50, Y = 100 }
        };
        var xml = XmlDumper.ToXml(toto, "Toto");
        Ce qui donne le XML suivant :
        Code XML : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        <Toto Foo="42" Bar="Hello world">
          <Baz X="50" Y="100" />
        </Toto>
        Bien sûr, ce n’est pas un remplacement de la "vraie" serialization XML... Ca ne permet pas de contrôler le schema XML généré, ni de reconvertir le XML en un objet. Mais c’est utile dans certains cas, par exemple pour générer un log XML sans schéma strict.
      • Classe DataProtectionProvider : fournit un moyen de chiffrer des données (texte ou binaire) sans avoir à gérer une clé de chiffrage. Ca se base sur la Data Protection API de Windows (via la classe ProtectedData). Les données chiffrées ne sont déchiffrables que par l'utilisateur qui les a chiffrées, ou un utilisateur sur la même machine (selon les paramètres utilisés). Pratique pour stocker des mots de passe de connexion par exemple…
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        var provider = new DataProtectionProvider();
        string password = "hello world";
        string protectedPassword = provider.ProtectString(password);
      • Classe LocalizedDescriptionAttribute : comme DescriptionAttribute, mais permet de spécifier une clé de ressource plutôt qu'un texte en dur, de façon à avoir une description localisée.
    • Assembly Developpez.Dotnet.System :
      • Propriété SystemInfos.ThemeInfo : renvoie des infos sur le thème (Aero, Luna, etc) utilisé par le système

    • Assembly Developpez.Dotnet.Windows (WPF) :
      • Classe RatingControl : corrigé les images par défaut (le fond n'était pas transparent, si bien que changer la couleur de fond du contrôle n'avait pas d'effet visible)
      • Classe FormView : contrôle permettant d’afficher et éditer les propriétés d’un objet sous forme de formulaire (comme avec les DetailsView et FormView d'ASP.NET). Il y a quelques types de champ prédéfinis (TextFormField, ComboBoxFormField, CheckBoxFormField), et on peut facilement créer des champs personnalisés en spécifiant le template manuellement :
        Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
        18
        19
        20
        21
        22
        <dvp:FormView IsInEditMode="True" DataContext="{Binding Movie}">
            <dvp:TextFormField Header="Title" Binding="{Binding Title}" />
            <dvp:ComboBoxFormField Header="Media type" Binding="{Binding MediaType}" ItemsSource="{dvp:EnumValues local:MediaType}" />
            <dvp:ComboBoxFormField Header="Director" Binding="{Binding Director}" ItemsSource="{Binding DataContext.Directors, ElementName=root}" DisplayMemberPath="Name" />
            <dvp:CheckBoxFormField Header="In stock" Binding="{Binding InStock}" />
            <dvp:FormField Header="Rating">
                <dvp:FormField.EditorTemplate>
                    <DataTemplate>
                        <dvp:RatingControl Value="{Binding Rating}"
                                           RatingMode="Decimal"
                                           Stretch="None" HorizontalAlignment="Left"/>
                    </DataTemplate>
                </dvp:FormField.EditorTemplate>
            </dvp:FormField>
            <dvp:FormField Header="Release date">
                <dvp:FormField.EditorTemplate>
                    <DataTemplate>
                        <DatePicker SelectedDate="{Binding ReleaseDate}" />
                    </DataTemplate>
                </dvp:FormField.EditorTemplate>
            </dvp:FormField>
        </dvp:FormView>
        Résultat :
      • Classe ErrorProvider : fournit des propriétés attachées pour mettre en valeur une erreur de saisie (dans un formulaire par exemple). Ce système est plus souple et plus léger à mettre en œuvre que le mécanisme existant dans WPF. L’approche ressemble un peu à celle du composant ErrorProvider de WinForms, sauf qu'on peut l'utiliser en XAML. Ce code :
        Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        8
        9
                <Label Grid.Row="0" Grid.Column="0" Content="Name" />
                <TextBox Grid.Row="0" Grid.Column="1"
                         Text="{Binding Name}"
                         dvp:ErrorProvider.ErrorMessage="{Binding Errors[Name]}" />
         
                <Label Grid.Row="1" Grid.Column="0" Content="Age" />
                <TextBox Grid.Row="1" Grid.Column="1"
                         Text="{Binding Age}"
                         dvp:ErrorProvider.ErrorMessage="{Binding Errors[Age]}" />
        Donne le résultat suivant :

        On peut aussi changer l'icône d'erreur, et son positionnement.
      • Classe ViewModelBase :
        • Méthode SetProperty : facilite les notifications de changement de valeur des propriétés. Au lieu d’écrire ça :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          private string _name;
          public string Name
          {
              get { return _name; }
              set
              {
                  if (value != _name)
                  {
                      _name = value;
                      OnPropertyChanged("Name");
                  }
              }
          }
          On peut maintenant écrire ça, pour obtenir le même effet :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          6
          private string _name;
          public string Name
          {
              get { return _name; }
              set { SetProperty(ref _name, value, "Name"); }
          }
      • Classe ViewModelExtensions :
        • Méthode InitializeViewModelCommands : fournit un mécanisme pour initialiser automatiquement les commandes d'un ViewModel, en décorant avec des attributs les méthodes qui implémentent les commandes. Cela évite pas mal de code de plomberie...
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          6
          7
          8
          9
          10
          11
          12
          13
          14
          15
          16
          17
          18
          19
          20
          21
          22
          23
          24
          25
          26
          27
          28
          29
          public class MyViewModel : ViewModelBase
          {
              public MyViewModel()
              {
                  this.InitializeViewModelCommands();
              }
           
              public ICommand FooCommand { get; set; }
              public ICommand BarCommand { get; set; }
           
              // Nom de la commande déterminé automatiquement
              // Convention : nom de la commande = nom de la méthode + "Command"
              [CommandExecute]
              private void Foo()
              {
              }
           
              // Nom de la commande spécifié explicitement
              [CommandExecute("BarCommand")]
              private void ExecuteBar ()
              {
              }
           
              [CommandCanExecute("BarCommand")]
              private bool CanExecuteBar()
              {
                  return true;
              }
          }
      • Classe CollectionViewShaper : permet la mise en forme (groupement, tri, filtrage) d'une CollectionView à l'aide de Linq (plus de détails ici), via des méthodes d’extension. Par exemple, si une ListView est bindée sur la collection People, on peut gérer la mise en forme comme ceci :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        var query =
            from p in People.ShapeView()
            where p.Age >= 18
            orderby p.LastName, p.FirstName
            group p by p.Country;
         
        query.Apply();
      • Classe ImageBehavior (affichage d’image GIF animée) : correction de bugs :
        • Certains fichiers GIF ne contiennent pas l’image entière dans chaque frame, mais seulement la partie qui change. Ce cas est maintenant géré correctement
        • Les métadonnées de l’image (délai, positionnement etc) ne pouvaient pas être lues sous Windows XP à cause d’une limitation de l’OS. Ce problème est maintenant résolu en décodant manuellement les métadonnées.
      • Classe ListBoxBehavior : fournit des fonctionnalités supplémentaires pour le contrôle ListBox
        • Propriété attachée SelectedItems : permet de binder la propriété SelectedItems de la ListBox (qui est normalement en lecture seule) pour gérer la multisélection en MVVM. Il faut juste créer une collection dans le ViewModel, et le behavior se charge de la synchroniser avec le SelectedItems de la ListBox :
          Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          <ListBox ItemsSource="{Binding Items}"
                   DisplayMemberPath="Name"
                   dvp:ListBoxBehavior.SelectedItems="{Binding SelectedItems}" />
      • Classe TextBlockBehavior : fournit des fonctionnalités supplémentaires pour le contrôle TextBlock
        • Propriété attachée RichText : permet d'afficher dynamiquement du texte riche dans un TextBlock, via une chaine qui contient du XAML. Cela permet notamment de localiser du texte mis en forme
          Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
          <TextBlock dvp:TextBlockBehavior.RichText="{Binding MessageWithRichXamlText}" />

    • Assembly Developpez.Dotnet.Windows.Forms (Windows Forms):
      • Classe WinFormsExtensions
        • Méthode d’extension ApplyResources : permet d'appliquer à la volée les ressources localisées d'une Form ou d'un UserControl quand on change de langue, sans avoir à recréer la Form :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          void SelectLanguage(string language)
          {
              Thread.CurrentThread.CurrentUICulture = CultureInfo.GetCultureInfo(language);
              this.ApplyResources();
          }
        • Méthode d’extension InvokeIfRequired : exécute une action sur le thread de l'UI, en utilisant Invoke si nécessaire :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          6
          7
          8
          9
          // Exécuté dans un worker thread...
          void Countdown()
          {
              for (int i = 10; i >= 0; i--)
              {
                  Thread.Sleep(1000);
                  label1.InvokeIfRequired(() => label1.Text = i.ToString());
              }
          }
    • Assembly Developpez.Dotnet.Drawing (GDI, librairie graphique de Windows Forms) :
      • Classe BitmapExtensions :
        • Méthode d'extension TransformColors : applique une matrice de transformation de couleurs à une image. Les transformations les plus courantes sont prédéfinies :
          Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
          1
          2
          3
          4
          5
          6
          // Niveaux de gris
          image.TransformColors(ColorTransforms.GrayScale);
          // Négatif
          image.TransformColors(ColorTransforms.Negative);
          // Sepia
          image.TransformColors(ColorTransforms.Sepia);
          Résultats :


    J'espère que toutes ces nouveautés vous seront utiles ! N'hésitez pas à nous suggérer des nouveautés et à signaler les bugs sur le gestionnaire de projet

    Téléchargements

  2. #2
    Membre chevronné
    Avatar de stailer
    Homme Profil pro
    Architecte technique
    Inscrit en
    Mars 2003
    Messages
    1 136
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 45
    Localisation : France, Hautes Pyrénées (Midi Pyrénées)

    Informations professionnelles :
    Activité : Architecte technique
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Mars 2003
    Messages : 1 136
    Points : 2 187
    Points
    2 187
    Billets dans le blog
    3
    Par défaut
    Très utiles ! j'aime beaucoup les nouveautés, notamment les ViewsModels et le CollectionView pour mes dévs en Silverlight.

    Merci beaucoup pour cette librairie gratuite !
    .o0o__St@iLeR__oOo.

    Lead Developer

    ASP.NET MVC - MCP/MCSD ASP.NET
    PHP Zend Framework / PhalconPHP
    Cordova/Xamarin IOS/Android
    Kendo UI - ExtJS - JQwidgets
    SQL Server / MySQL

  3. #3
    Membre émérite

    Homme Profil pro
    Software Developer
    Inscrit en
    Mars 2008
    Messages
    1 470
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Royaume-Uni

    Informations professionnelles :
    Activité : Software Developer

    Informations forums :
    Inscription : Mars 2008
    Messages : 1 470
    Points : 2 368
    Points
    2 368
    Par défaut
    Merci infiniment tomlev, excellent travail

    Est-il possible de proposer de nouvelles extensions ? Si oui, comment ?

  4. #4
    Rédacteur/Modérateur


    Homme Profil pro
    Développeur .NET
    Inscrit en
    Février 2004
    Messages
    19 875
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 42
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Développeur .NET
    Secteur : High Tech - Éditeur de logiciels

    Informations forums :
    Inscription : Février 2004
    Messages : 19 875
    Points : 39 749
    Points
    39 749
    Par défaut
    Citation Envoyé par alex_vino Voir le message
    Est-il possible de proposer de nouvelles extensions ? Si oui, comment ?
    Salut,

    Tu peux proposer tes contributions sur le forum du projet, ou sur le forum Contribuez de la rubrique .NET

Discussions similaires

  1. Sortie de la version 0.6 de Dvp.NET
    Par tomlev dans le forum Dvp.NET
    Réponses: 8
    Dernier message: 08/06/2012, 21h24
  2. Sortie de la version 0.4 de Dvp.NET
    Par tomlev dans le forum Dvp.NET
    Réponses: 0
    Dernier message: 02/06/2011, 19h35
  3. Sortie de la version 0.3 de Dvp.NET
    Par tomlev dans le forum Dvp.NET
    Réponses: 0
    Dernier message: 09/01/2011, 23h17
  4. Sortie de la version 0.2 de Dvp.NET
    Par tomlev dans le forum Dvp.NET
    Réponses: 9
    Dernier message: 26/06/2010, 18h36
  5. [Eclipse 3.1][News] Sortie de la version M5 d'Eclipse 3.1
    Par bidon dans le forum Eclipse Java
    Réponses: 1
    Dernier message: 20/02/2005, 10h46

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo