La version 0.6 de la librairie Dvp.NET est disponible !



Dvp.NET est une bibliothèque de classes pour les applications .NET, développée par des membres de Developpez.com. Elle couvre de nombreux aspects du développement : manipulation de collections, de chaines de caractères, accès aux données, interface graphique, algorithmes métier... Bref, c'est une sorte de couteau suisse pour tous les développeurs .NET, un peu à la manière de Boost pour C++ (bon, on a encore un peu de travail avant de pouvoir vraiment se comparer à Boost )

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.

Au programme de cette version : du Linq, de l'accès aux données, du WPF, du Windows Forms... bref, de tout, ou presque . Je vous laisse examiner le détail de nouveautés !

  • Assembly Developpez.Dotnet
    • Classe EnumerableExtensions
      • Méthode d'extension Flatten : permet "d'aplatir" une hiérarchie d'objets. Cette méthode était déjà présente dans les versions précédentes, mais cette nouvelle surcharge permet d'obtenir le niveau de chaque noeud dans la hiérarchie :

        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        var flat = rootNodes.Flatten(
                    node => node.Children,
                    TreeTraversalMode.DepthFirst,
                    (node, lvl) => new { Level = lvl, Name = node.Name });
        Résultat :
        Level	Name
        0	Node 1
        1	Node 1.1
        2	Node 1.1.1
        1	Node 1.2
        0	Node 2
        1	Node 2.1
      • Méthodes d'extensions InsertRange, RemoveRange et RemoveAll : équivalentes aux méthodes du même nom de List<T>, mais s'appliquent à n'importe quelle ICollection<T> (ou IList<T> pour InsertRange)
      • Méthode d'extension DistinctUntilChanged : enlève les doublons contigus d'une séquence, i.e. [1, 1, 2, 3, 3, 3, 2, 3, 1, 1] devient [1, 2, 3, 2, 3, 1] (inspiré de la méthode Observable.DistinctUntilChanged de Rx, mais appliqué aux IEnumerable<T>)
    • Classe LinqHelper
      • Méthode Generate : génère une séquence à partir d'une valeur initiale, d'une condition d'arrêt et d'une fonction de transition (encore inspiré de Rx). Exemple :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        // Génère les nombres de Fibonacci inférieurs à 100
        var fibonacci =
            LinqHelper.Generate(
                new { value = 0, next = 1 },
                s => s.value < 100,
                s => new { value = s.next, next = s.value + s.next },
                s => s.value);
    • Classe DictionaryExtensions
      • Méthode d'extension GetOrAdd : tente de récupérer une valeur dans le dictionnaire ; si la clé demandée est absente du dictionnaire, crée la valeur avec la fonction spécifiée et l'ajoute au dictionnaire.
        Ça permet de simplifier ce genre de code :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        Foo foo;
        if (!_foos.TryGetValue(key, out foo))
        {
            foo = CreateFoo(key);
            _foos[key] = foo;
        }
        return foo;
        En ceci :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        return _foos.GetOrAdd(key, k => CreateFoo(k));
         
        // ou encore plus simple :
        return _foos.GetOrAdd(key, CreateFoo);
      • Méthode d'extension GetOrCreate : comme GetOrAdd, mais n'ajoute pas la valeur générée au dictionnaire
    • Classe DataExtensions
      • Méthode d'extension SetParameters : permet de définir les paramètres d'une requête via un objet :

        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        string sql = "INSERT INTO Persons(Id, LastName, FirstName, DateOfBirth) VALUES (@id, @lastName, @firstName, @dateOfBirth)";
        using (var command = connection.CreateCommand(sql))
        {
            var parameters = new
            {
                Id = Guid.NewGuid(),
                LastName = "Morrison",
                FirstName = "Jim",
                DateOfBirth = new DateTime(1943, 12, 8)
            };
            command.SetParameters(parameters).ExecuteNonQuery();
        }
      • Méthode d'extension Query : exécute une requête en utilisant les paramètres spécifiés :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        string sql = "SELECT * FROM Persons WHERE Country = @country AND Age > @minAge";
        var parameters = new { Country = "France",  MinAge = 18 };
        foreach (var result in connection.Query(sql, parameters))
        {
            Console.WriteLine("{0} {1}", result.GetString("FirstName"), result.GetString("LastName"));
        }
      • Méthode d'extension QueryScalar : comme Query, mais renvoie un scalaire :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        string sql = "SELECT Age FROM Persons WHERE Id = @id";
        var parameters = new { Id = 42 };
        int age = (int)connection.QueryScalar(sql, parameters);
      • Méthode d'extension Execute : comme Query, mais pour une commande qui ne renvoie pas de résultat :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        8
        9
        string sql = "INSERT INTO Persons(Id, LastName, FirstName, DateOfBirth) VALUES (@id, @lastName, @firstName, @dateOfBirth)";
        var parameters = new
        {
            Id = Guid.NewGuid(),
            LastName = "Morrison",
            FirstName = "Jim",
            DateOfBirth = new DateTime(1943, 12, 8)
        };
        connection.Execute(sql, parameters);
    • Classe StringExtensions
      • Méthode d'extension ReplaceAt : remplace un caractère à la position spécifiée
    • Classe CompareExtensions
    • Classe CoreExtensions
      • Méthode d'extension FormatWithTemplate : pour formater un objet à l'aide de StringTemplate :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        string text = user.FormatWithTemplate("{Name} est né le {DateOfBirth:dd MMMM yyyy} et habite à {City}");
      • Méthodes d'extension Add(IntPtr, int) et Subtract(IntPtr, int) : ajoute ou soustrait un offset à un pointeur.
    • Classe VersionNumber : représente un numéro de version qui respecte les règles du semantic versioning
    • Classe TrieDictionary<T> : dictionnaire basé sur une trie, ce qui permet des recherches très rapides par préfixe de la clé.
    • Classe IniFile : gestion plus fine de l'encodage. Il est maintenant possible de spécifier l'encodage à utiliser pour le fichier INI.
    • Classe StringTemplate : amélioration des performances (ajout d'un cache pour ne pas devoir parser le même template plusieurs fois)


  • Assembly Developpez.Dotnet.Windows
    • Classe InputBehavior
      • Propriété attachée UseCultureDependentDecimal : permet d'obtenir un comportement identique à celui d'Excel lors de la saisie de nombre décimaux, à savoir que le point du pavé numérique sera converti en le séparateur décimal de la culture courante.
    • Classe TextBlockBehavior
      • Propriété attachée RichText : corrigé un plantage quand le texte riche contient des caractères accentués ou autres caractères spéciaux
    • Classe GroupName : permet de restreindre un nom de groupe (pour les RadioButtons par exemple) à une portée locale. Cela permet, dans le cas d'un groupe de RadioButtons dans un template, d'éviter que l'exclusion mutuelle ne s'étende à toutes les instances du template. Exemple:
      Code XAML : Sélectionner tout - Visualiser dans une fenêtre à part
      1
      2
      3
      4
      5
      <StackPanel dvp:GroupName.IsGroupNameScope="True">
          <RadioButton Content="Foo" GroupName="{dvp:GroupName myGroup}" />
          <RadioButton Content="Bar" GroupName="{dvp:GroupName myGroup}" />
          <RadioButton Content="Baz" GroupName="{dvp:GroupName myGroup}" />
      </StackPanel>
    • Classe GridViewBehavior : amélioration du tri : si un tri est déjà appliqué à la liste au départ, le glyphe correspondant est affiché dans l'en-tête de colonne
    • Classe DependencyObjectExtensions :
      • Méthode d'extension FindDescendants : renvoie tous les descendants visuels d'un élément qui ont le type spécifié
    • Classe ViewModelBase : nettoyage des membres inutiles, extraction d'une classe de base ObservableBase
    • Classe ObservableBase : implémentation basique de INotifyPropertyChanged


  • Assembly Developpez.Dotnet.Windows.Forms
    • Classe WinFormsExtensions
      • Méthode d'extension FlashWindow : fait clignoter la fenêtre pour attirer l'attention de l'utilisateur (utilise l'API Windows FlashWindowEx)
    • Classe ItemStyleListBox : une ListBox qui permet d'appliquer un style différent à chaque élément, via un évènement (même principe que pour ItemStyleComboBox)


  • Assembly Developpez.Dotnet.Drawing
    • Classe BitmapExtensions
      • Méthode d'extension RemoveTransparency : enlève la transparence d'une image en la plaçant sur un fond de la couleur spécifiée
      • Méthode d'extension LockPixels : comme LockBits (pour l'accès rapide aux pixels de l'image), mais beaucoup plus simple à utiliser... Ça donne par exemple quelque chose comme ça :
        Code C# : Sélectionner tout - Visualiser dans une fenêtre à part
        1
        2
        3
        4
        5
        6
        7
        8
        9
        using (var pixels = bitmap.LockPixels(ImageLockMode.ReadWrite))
        {
            for (int y = 0; y < pixels.Height; y++)
            for (int x = 0; x < pixels.Width; x++)
            {
                Color c = pixels[x, y];
                pixels[x, y] = TransformColor(c);
            }
        }
    • Classe ColorExtensions
      • Méthode d'extension ToHsv : convertit une couleur RGB en HSV
      • Méthode d'extension ToHsl : convertit une couleur RGB en HSL
      • Méthode d'extension ToRgb : convertit une couleur HSV ou HSL en RGB
      • Méthode d'extension ToGrayScale : convertit une couleur en niveau de gris


  • Assembly Developpez.Dotnet.System
    • Classes FileMoveOperation et FileCopyOperation : 2 petites améliorations
      • Méthode ExecuteAsync : exécute l'opération de façon asynchrone ; les notifications de progression sont déclenchées sur le thread qui a lancé l'opération (en général le thread UI)
      • Evènement Completed : se produit quand l'opération est terminée


  • Documentation
    Vous l'avez peut-être déjà remarqué car c'est en place depuis quelques mois, mais la documentation a été nettement (quoique discrètement) améliorée :
    • Correction d'un bug qui faisait apparaitre n'importe où certaines méthodes d'extension
    • Améliorations de la version en ligne :
      • Chargement dynamique de l'arborescence des classes et namespaces, ce qui fait que la page se charge plus rapidement
      • Index des mots-clés
      • Recherche par mot-clé (il faut rechercher le mot exact, mais c'est quand même un progrès...)
      • Lien direct vers une page de la doc


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