Code sample

[WPF] Tri automatique d’un GridView : suite

Il y a quelques mois, j’avais publié un billet où j’expliquais comment trier automatiquement un GridView lors du clic sur un en-tête de colonne. J’avais laissé un point ouvert : l’ajout d’un symbole dans l’en-tête de colonne pour indiquer visuellement la direction du tri. C’est maintenant chose faite ! Pour arriver à ce résultat, j’ai utilisé un Adorner : c’est un composant qui permet de dessiner “par-dessus” un élément graphique existant, sur une couche de dessin indépendante.

[WPF] Une markup extension qui met à jour sa cible

Si vous avez lu mes précédents billets sur le sujet, vous savez que je suis un grand fan des markup extensions… Cependant, celles-ci ont une limitation qui peut s’avérer assez gênante : elles ne sont évaluées qu’une seule fois. Il serait pourtant utile de pouvoir les réévaluer pour mettre à jour la propriété cible, comme pour un binding… Cela peut être utile dans différents cas, notamment : si la valeur de la markup extension peut changer en réponse à un évènement

[C#] Relation parent/enfant et sérialisation XML

Me revoilà avec un peu de retard, j’ai un peu manqué de temps libre ces dernières semaines… Voilà donc un petit post pour présenter une idée qui m’est venue récemment. Pour une fois, il ne sera pas question de WPF, c’est de conception C# qu’il s’agit ! Le problème Il est assez courant, dans un programme, d’avoir un objet parent qui possède une collection d’enfants ayant une référence vers leur parent.

[Windows Forms] Glisser-déplacer automatique de contrôles (DragMove)

Je ressors de mes tiroirs un code que j’avais écrit il y a quelque temps, et dont je voudrais vous faire profiter… Il existe en WPF une méthode très pratique pour déplacer une fenêtre sans bordure : Window.DragMove. Elle s’utilise comme ceci : private void Window_MouseDown(object sender, MouseButtonEventArgs e) { this.DragMove(); } A partir de l’appel de cette méthode, la fenêtre est déplacée avec la souris jusqu’à ce que le bouton soit relâché.

[WPF] Binding sur une collection asynchrone

Comme je l’avais évoqué dans mon précédent post, on ne peut pas ajouter des éléments à une ObservableCollection à partir d’un autre thread si une vue est bindée sur la collection : cela provoque une NotSupportedException. Prenons l’exemple d’une ListBox bindée sur une collection de chaines de caractères appartenant au ViewModel : private ObservableCollection<string> _strings = new ObservableCollection<string>(); public ObservableCollection<string> Strings { get { return _strings; } set { _strings = value; OnPropertyChanged("Strings"); } } <ListBox ItemsSource="{Binding Strings}"/> Si on ajoute des éléments à cette collection hors du thread principal, on obtient l’exception citée plus haut.

[WPF] Binding asynchrone sur une propriété du ViewModel

Mise à jour : Comme l’a très justement indiqué Jérémy en commentaire, la propriété IsAsync du Binding permet de faire à peu près la même chose beaucoup plus simplement… Bien que ma méthode puisse servir pour certains besoins spécifiques, dans la plupart des cas la propriété IsAsync est probablement le meilleur choix ! Je laisse le billet malgré tout, ne serait-ce que pour la classe SwitchBinding qui me semble assez utile… J’ai eu récemment besoin, dans une application basée sur le pattern MVVM, d’afficher une propriété dont la valeur était assez longue à obtenir (récupérer par une requête HTTP).

[WPF] Tri automatique d'un GridView lors du clic sur une colonne

Il est assez simple, en WPF, de présenter des données sous forme de grille, grâce à la classe GridView. Pour le tri, en revanche, ça se complique… Avec le DataGridView de Windows Forms, c’était “automagique” : quand l’utilisateur cliquait sur un en-tête de colonne, le tri se faisait automatiquement sur cette colonne. En WPF, par contre, il faut un peu mettre les mains dans le cambouis… La méthode préconisée par Microsoft pour trier un GridView lors du clic sur une colonne est décrite dans cet article ; elle est basée sur l’évènement Click du GridViewColumnHeader.

[WPF] Utiliser les InputBindings avec le pattern MVVM

Si vous développez des applications WPF en suivant le design pattern Model-View-ViewModel, vous vous êtes peut-être déjà trouvé confronté au problème suivant : comment, en XAML, lier un raccourci clavier ou une action de la souris à une commande du ViewModel ? Idéalement, on aimerait pouvoir faire comme ça : <UserControl.InputBindings> <KeyBinding Modifiers="Control" Key="E" Command="{Binding EditCommand}"/> </UserControl.InputBindings> Malheureusement, ce code ne fonctionne pas, pour deux raisons : La propriété Command n’est pas une DependencyProperty, on ne peut donc pas faire de binding dessus Les InputBindings ne font pas partie de l’arbre logique ou visuel du contrôle, ils n’héritent donc pas du DataContext Une solution, bien sûr, serait de passer par le code-behind pour créer les InputBindings, mais en général, dans une application développée selon le pattern MVVM, on préfère éviter d’écrire du code-behind.

Créer un lecteur RSS en 5 minutes

Aujourd’hui, je suis tombé par hasard sur une petite classe bien pratique : SyndicationFeed. Cette classe, apparue dans le framework 3.5, permet de manipuler des flux de syndication (comme RSS 2.0 ou Atom 1.0) avec un minimum de code. On peut l’utiliser pour créer et diffuser des flux, ou pour lire des flux existants. Par exemple, voilà comment récupérer le fil d’actualité de Google News et afficher son titre, son lien d’origine et les titres de ses articles :

[WPF] Coller une image du presse-papier (bug dans Clipboard.GetImage)

Hum… 2 mois depuis mon précédent (et premier) post… il faudra que j’essaie d’être un peu plus régulier à l’avenir ;-) Si vous avez déjà essayé d’utiliser la méthode Clipboard.GetImage avec WPF, vous avez dû avoir une mauvaise surprise… En effet, cette méthode renvoie un InteropBitmap qui, dans certains cas (voire tout le temps), refuse de s’afficher dans un contrôle Image : aucune exception n’est levée, la taille de l’image est correcte, mais… l’affichage reste désespérément vide, ou alors l’image est méconnaissable.