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
Méthode d’extension Tee : comme StreamExtensions.Tee, mais pour les TextWriter. Exemple :// 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");
}
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
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 :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é :// 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 :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é :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é :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 :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 :var result =
list1.LeftOuterJoin(
list2,
x1 => x1.Id,
x2 => x2.Id,
(x1, x2) => new { x1, x2 });
Méthode d’extension Truncate : tronque une date au composant spécifié (année, mois, jour, heure, minute, seconde, milliseconde). Exemple :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).
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.
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...MyStruct obj = new MyStruct();
typeof(MyStruct).GetProperty("Foo").SetValue(ref obj, 42);
Classe EncodingExtensions :string text;
if (!Encoding.UTF8.TryGetString(bytes, out text))
Console.WriteLine("Données non valides");
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 :try
{
Foo();
}
catch (TargetInvocationException ex)
{
throw ex.InnerException.PreserveStackTrace();
}
Comme promis lors de la sortie de la version précédente : conversion de nombres en anglais (US et GB) !
Classe OrderedDictionary
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 :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 :
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…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.
Propriété SystemInfos.ThemeInfo : renvoie des infos sur le thème (Aero, Luna, etc) utilisé par le système
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 :Stretch="None" HorizontalAlignment="Left"/>
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 :dvp:ErrorProvider.ErrorMessage="{Binding Errors}" />
dvp:ErrorProvider.ErrorMessage="{Binding Errors}" />
Donne le résultat suivant :

On peut aussi changer l'icône d'erreur, et son positionnement.
Méthode SetProperty : facilite les notifications de changement de valeur des propriétés. Au lieu d’écrire ça :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 :
private string _name;
public string Name
{
get { return _name; }
set { SetProperty(ref _name, value, "Name"); }
}
Classe ViewModelExtensions :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"
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 :var query =
from p in People.ShapeView()
where p.Age >= 18
orderby p.LastName, p.FirstName
group p by p.Country;
query.Apply();
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 ListBoxdvp:ListBoxBehavior.SelectedItems="{Binding SelectedItems}" />
Classe TextBlockBehavior : fournit des fonctionnalités supplémentaires pour le contrôle TextBlock
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 :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 :// Exécuté dans un worker thread...
void Countdown()
{
for (int i = 10; i >= 0; i--)
{
Thread.Sleep(1000);
label1.InvokeIfRequired(() => label1.Text = i.ToString());
}
}
Méthode d'extension TransformColors : applique une matrice de transformation de couleurs à une image. Les transformations les plus courantes sont prédéfinies :// 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
Vous avez lu gratuitement 1 358 articles depuis plus d'un an.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.
Soutenez le club developpez.com en souscrivant un abonnement pour que nous puissions continuer à vous proposer des publications.

