Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Thomas Lebrun

Tout sur WPF, LINQ, C# et .NET en général !

Actualités

[WPF] Comment cloner un contrôle WPF ?

La semaine dernière, pour les besoins d'un client, j'ai eu besoin de trouver le moyen de cloner un objet graphique WPF afin d'en avoir une copie.

Dans la plupart des cas, on peut se dire qu'appeler la méthode Clone suffit. Seul petit problème: lorsque l'on souhaite cloner un UserControl, cette méthode n'est pas disponible.

Fort heureusement, dans ce post du forum MSDN US, vous trouverez une méthode qui réalisera le clonage de vos objets.

La technique est simple mais efficace: on obtient la représentation XAML du contrôle que l'on souhaite cloner et on appelle la méthode XamlReader.Load en passant en paramètre le code XAML à instancier.

Pour vous faire gagner du temps, voici le code de la méthode:

public static UIElement cloneElement(UIElement orig)

{

    if (orig == null)

        return (null);

 

    string s = XamlWriter.Save(orig);

 

    StringReader stringReader = new StringReader(s);

 

    XmlReader xmlReader = XmlTextReader.Create(stringReader, new XmlReaderSettings());

 

    return (UIElement)XamlReader.Load(xmlReader);

}

En espérant que cela vous utile Wink

 

A+

[Perso] Tom.MVP.Years++ && Tom.MVP.Category = "Client Application Development"

En voila un titre sans doute un peu bizarre Big Smile Enfin bref, juste pour vous dire que je viens d'être renouvellé MVP avec cependant un changement de catégorie: de MVP C#, je passe à MVP Client Application Development.

Cette catégorie contient tout les MVPs qui travaillent, de prêt ou de loin, avec les technologies de développement d'application clientes mais principalement WPF et/ou Silverlight.

Je tenais donc à remercier une nouvelle fois Microsoft pour me faire à nouveau confiance et me décerner cette reconnaissanceSmile

 

A+

[Silverlight] Retrouver la WatermarkTextBox de Silverlight 2

Dans la Beta 1 de Silverlight 2, on disposait d'un contrôle bien sympathique nommé WatermarkTextBox. Ce contrôle vous permettait d'afficher, dans la zone de saisie, du texte qui disparaitrait dès lors que l'utilisateur entrerait lui-même du texte: très pratique sur les IHM où l'on ne dispose pas de beaucoup de place:

Cependant, on est au regret de constater que ce contrôle n'existe plus dans la Beta 2. Certes, il est très facile de le refaire mais bon, cela reste du travail en plus....
De même, on me demande souvent pourquoi Microsoft a décidé de retirer ce contrôle de la liste des contrôles disponibles avec Silverlight.

Je dois reconnaitre que je me posais la même question, sans vraiment avoir d'idée bien précise et je reconnais que la réponse, vue sur le blog de Kathy Kam, permet de clarifier les choses:

"We decided to remove the control because in a future version of Silverlight, we will be adding a “Watermark” property to TextBox."

Bref, pour ceux qui souhaitent re-disposer rapidement de ce contrôle, rendez-vous sur le blog de Kathy, qui le met en téléchargement (code source et tests unitaires): http://blogs.msdn.com/kathykam/archive/2008/06/23/watermarkedtextbox-for-silverlight-2-beta-2.aspx

 

A+

[WPF] Exemple d'application utilisant WPF et ADO.NET

La majorité des exemples et/ou démonstrations que l'on rencontre à l'heure actuelle à propos de WPF utilise les nouvelles technologies d'accès aux données: LINQ To SQL ou ADO.NET Entity Framework.

Seul problème: tout le monde ne peut pas encore utiliser toutes ces technologies en même temps.

Ainsi, et pour répondre à certaines questions/demandes, j'ai développé une petite application qui montre comment utiliser ADO.NET avec WPF. Rien de bien méchant, je vous l'accorde, mais cela permettra à toute les personnes qui se posent la question d'avoir une réponse Smile

L'application peut-être téléchargée ici: DemoWPFWithDB

 

A+

 

PS: Penser à changer la chaîne de connexion et, éventuellement, à installer la base Northwind sur votre machine pour que l'exemple fonctionne.

[WPF] Comment appeler une méthode depuis du code XAML ?

Beaucoup de gens se demande s'il est possible d'appeler une méthode depuis son code XAML. Par exemple, comment appeler une méthode d'un Web Service directement depuis son XAML ?

Il est possible d'y parvenir en utilisant un ObjectDataProvider. Prenons l'exemple de la classe suivante:

public class BusinessClass

{

    public string SayHelloToSomeOne(string someone)

    {

        return !string.IsNullOrEmpty(someone) ? string.Format("Hello {0}", someone) : "Hello everybody";

    }

}

Comment parvenir à appeler cette méthode depuis un ObjectDataProvider ? Tout simplement en spécifiant les propriétés ObjectType et MethodName de notre objet:

<ObjectDataProvider x:Key="odp" ObjectType="local:BusinessClass" MethodName="SayHelloToSomeOne">

    <ObjectDataProvider.MethodParameters>

        <s:String>Thomas</s:String>

    </ObjectDataProvider.MethodParameters>

</ObjectDataProvider>

A noter qu'il est possible d'utiliser la propriété ObjectInstance pour se lier à une instance déjà existante.

Ensuite, dans votre code XAML, il ne vous reste plus qu'à vous lier à votre objet, via un petit binding:

<TextBlock x:Name="tb" Grid.Row="0" Text="{Binding Source={StaticResource odp}}" />

De plus, si vous souhaitez modifier les paramètres de la méthode appellée, il vous convient d'accéder, par code, à votre ObjectDataProvider:

private void btn_Click(object sender, RoutedEventArgs e)

{

    var odp2 = Resources["odp"] as ObjectDataProvider;

    if (odp2 != null)

    {

        odp2.MethodParameters[0] = string.Empty;

        odp2.Refresh();  

    }

}

Et le tour est joué Smile

 

A+

[WPF] Bug avec les BitmapEffects

Si vous travaillez avec les BitmapEffect de WPF, vous avez peut-être remarqué un bug pour le moins génant. Essayer le code suivant:

<Window x:Class="TestSmyley.Window1"

    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

    Title="Window1" Height="300" Width="300">

    <Grid>

        <Rectangle>

            <Rectangle.Fill>

                <LinearGradientBrush StartPoint="0,0" EndPoint="0,1">

                    <GradientStop Color="White" Offset="0"/>

                    <GradientStop Color="Black" Offset="1"/>

                </LinearGradientBrush>

            </Rectangle.Fill>

        </Rectangle>

 

        <TextBlock Name="MyBox" VerticalAlignment="Bottom" TextAlignment="Center" Foreground="Silver">

            <TextBlock.BitmapEffect>

                <OuterGlowBitmapEffect GlowColor="White" GlowSize="2"/>

            </TextBlock.BitmapEffect>

        </TextBlock>

 

        <Button Margin="0,5,0,0" Width="100" Height="40" Click="Button_Click">Mettre du texte</Button>

        <Button Margin="0,120,0,0" Width="100" Height="40" Click="Button_Click_1">Effacer le texte</Button>

    </Grid>

 

</Window>

public partial class Window1 : Window

{

    public Window1()

    {

        InitializeComponent();

    }

 

    private void Button_Click(object sender, RoutedEventArgs e)

    {

        MyBox.Text = "Ceci est du texte";

    }

 

    private void Button_Click_1(object sender, RoutedEventArgs e)

    {

        MyBox.Text = "";

    }

}

Si vous cliquez sur le deuxième bouton, vous vous attendez à ce que le texte de la TextBlock disparaisse. Hors, à l'exécution, il s'avère que cela n'est pas le cas: le contenu est bien remis à zéro mais l'interface graphique, elle, ne change pas:

image

Il s'agit en effet d'un bug connu par Microsoft qui propose ceci, comme solution:

private void Button_Click_1(object sender, RoutedEventArgs e)

{

    object be = MyBox.GetValue(TextBlock.BitmapEffectProperty);

    MyBox.ClearValue(TextBlock.BitmapEffectProperty);

    MyBox.ClearValue(TextBlock.TextProperty);

    MyBox.SetValue(TextBlock.BitmapEffectProperty, be);

}

Il est à noter qu'il s'agit d'une solution "temporaire" car l'utilisation de la propriété BitmapEffect est déprécié dans le Service Pack 1 !

En savoir plus: http://forums.msdn.microsoft.com/en-US/wpf/thread/d2a5ec3c-db4b-4360-8265-84552fa2d3bf/

 

A+

[Silverlight] Comment migrer son "Custom Control" de la Beta 1 à la Beta 2

Avec l'arrivée de Silverlight 2 Beta 2, on peut remarquer qu'il y a quand même pas mal de "breaking changes" entre ces 2 versions. L'une des plus importantes, à mon sens, est la méthodologie utilisée pour la création de contrôles personnalisés.

Avant, nous étions obligé d'hériter d'un contrôle de Silverlight, de surcharger une méthode (OnApplyTemplate) et de définir, à la main, l'apparence de notre contrôle. Avec cette nouvelle version, on découvre un nouvel élément qui entre en jeu: le Visual State Manager, qui vous permettra de définir (via Expression Blend), les différents états et les transitions pour un contrôles.

Certes, cela est très pratique mais cela signifie-t-il que tout le travail que l'on a fait sur la Beta 1 doit-être refait ? Par forcément ! Smile

En effet, si vous souhaitez continuer à développer vos propres contrôles, il faut trouver le moyen d'indiquer au moteur Silverlight que les styles/templates de vos contrôles se trouvent dans le fichier generic.xaml. Pour cela, rien de plus simple: il vous suffit d'indiquer le style par défaut de vos contrôles, en rajoutant une ligne dans le constructeur:

public ProgressBar() : base()

{

    DefaultStyleKey = typeof(ProgressBar);

}

Ensuite, surchargez toujours la méhode OnApplyTemplate (attention, la signature a changé: avant, le modificateur était protected et on est maintenant passé à public):

public override void OnApplyTemplate()

Et c'est tout: votre contrôle devrait remarcher correctement :)

Bien que fonctionnelle, cette technique requiert cependant d'écrire pas mal de code pour faire passer le contrôle d'un état à un autre. Grâce au Visual State Manager, le designer a la possibilité de gérer cela directement dans Blend ! Pour avoir un aperçu, je vous recommande cette vidéo: Aperçu du Visual State Manager.

 

A+

[Silverlight] Silverlight 2 Beta 2 est disponible en téléchargement !

Microsoft nous l'avais promis avant la fin de la semaine, c'est maintenant chose faite !

Vous pouvez télécharger le Runtime Silverlight 2 Beta 2 a cette addresse:

http://www.microsoft.com/silverlight/resources/install.aspx?v=2.0

Pour les extensions Visual Studio, c'est par ici: Install Silverlight Tools Beta 2 for Visual Studio 2008

Enfin, vous trouverez une nouvelle version de Blend et du Deep Zomm Composer: Install Expression Blend 2.5 June 2008 Preview & Install Deep Zoom Composer


Pour en savoir plus, un seul lien: http://weblogs.asp.net/scottgu/archive/2008/06/06/silverlight-2-beta2-released.aspx

 

A+

[WPF] Bug & Fix pour le contrôle "Graph" du Bag'O'Trick de Kevin Moore

Pour les besoins d'un projet WPF, l'équipe avec laquelle je travaille a eu besoin d'utiliser le fameux contrôle Graph, disponible dans le Bag'O'Trick de Kevin Moore.

Ce contrôle est très pratique et relativement simple à utiliser mais il s'avère que nous avons identifié un bug lorsque vous changez les nodes à la volée. Si vous réinstancier le contrôle à chaque fois, avec de nouvelles nodes, pas de problèmes. Seulement si vous conservez toujours le même contrôle masi que vous changez les nodes dynamiquement, vous risquez de vous retrouvez avec un contrôle qui fonctionne correctement la première fois mais qui n'affiche pas son élément central lors du changement des noeuds (y compris du noeud central). Pour être plus parlant, voici ce que vous risquez d'obtenir:

image

Comme vous pouvez le constatez, il semble manquer quelque chose au milieu.... Pour corriger ce problème, la solution est toute simple. Récupérer les sources du Graph sur le site de Kevin et ouvrez le fichier Graph.cs. Là, localisez les lignes de code suivante (aux alentours des 700):

_nodePresenters.Clear();

_nodePresenters.AddRange(newChildren);

Et juste au dessus, rajoutez le code suivant:

if (_centerDataInUse != null)

{

    SetUpCleanCenter(_centerDataInUse);

}

Pour que cela fonctionne, vous devrez cependant modifier le code de la méthode SetUpCleanCenter pour mettre en commentaire cette ligne qui peut, parfois, provoquer une exception:

Debug.Assert(m_centerGraphContentPresenter == null);

A présent, si vous réexécutez votre code, vous remarquez que tout fonctionne parfaitement bien:

image


Il est cependant possible, si vous faîtes ceci, que vous remarquiez que lorsque vous cliquez sur un des noeuds du graph, il reste affiché et ne disparaisse pas. Pour corriger ce problème, là encore, c'est très simple. Mettez en commentaire cette ligne de code, qui doit se trouver vers la ligne 598 de la méthode handleChanges:

_nodePresenters [ i ] = null;

 

En espérant que cela puisse en aider quelques-uns !

 

A+

[Article/WPF] Comment créer votre propre contrôle avec WPF

La création de contrôles, pour une application WPF (Windows Presentation Foundation), est une opération qui peut-être très simple à mettre en place ou bien qui peut prendre un certains temps lorsque l'on désire y ajouter un maximum de fonctionnalités.

Pour que vous sachiez comment vous y prendre, je vous ai écrit un petit article qui décrit les 2 façons de développer un contrôle avec WPF:

  • Créer un UserControl
  • Créer un Custom Control

Pour en savoir plus, c'est par ici: Comment créer votre propre contrôle avec WPF

N'hésitez pas à me faire part de vos commentaires/avis/etc. et j'espère que cela vous plaira et/ou vous sera utile !

 

A+

[WPF] Comment scroller automatiquement dans une ListBox ?

La ListBox de WPF est un composant très pratique qui vous permet de stocker différents types de données.

Lorsqu'il n'y a pas assez de place pour afficher tous les éléments, une scrollbar (horizontale et/ou verticale) apparait, vous permettant d'effectuer un défilement. Si vous en avez besoin, vous avez la possibilité de provoquer le défilement automatique par du code: cela peut s'avérer très pratique à certains moment, par exemple lorsque vous ajouter, à la volée, un élément (en effet, la ListBox ne défile pas automatiquement sur le dernier élément ajouté).

Pour effectuer ce défilement par code, vous avez plusieurs possibilités. Tout d'abord, vous pouvez appeler la méthode ScrollIntoView, qui prend en paramètre l'objet vers lequel vous souhaitez défilé:

this.lb.ScrollIntoView(this.lb.Items.GetItemAt(this.lb.Items.Count - 1));

Une autre possibilité est d'accéder au composant ScrollViewer qui compose la ListBox. Pour cela, rien de plus simple: il suffit de faire appel à la méthode VisualTreeHelper.GetChild:

Border border = VisualTreeHelper.GetChild(this.lb, 0) as Border;

 

if (border != null)

{

    ScrollViewer scrollviewer = VisualTreeHelper.GetChild(border, 0) as ScrollViewer;

 

    if (scrollviewer != null)

    {

        //

    }

}

Une fois que vous avez accès au ScrollViewer, libre à vous d'utiliser les méthodes de cet object, comme:

  • ScrollToEnd
  • ScrollToBottom
  • Etc.

Une des méthodes intéressantes est la méthode ScrollToVerticalOffset, qui vous permet de faire défiler, de façon verticale, le contenu à la position précise d'un offset. Il est à noter que la même version existe en version horizontale (ScrollToHorizontalOffset):

Border border = VisualTreeHelper.GetChild(this.lb, 0) as Border;

 

if (border != null)

{

    ScrollViewer scrollviewer = VisualTreeHelper.GetChild(border, 0) as ScrollViewer;

 

    if (scrollviewer != null)

    {

        scrollviewer.ScrollToVerticalOffset(scrollviewer.ViewportHeight);

    }

}

 

Bon développement à tous !

 

A+

[Event] Les inscriptions pour la PDC 2008 sont ouvertes !

Microsoft vient d'ouvrir les inscriptions pour la PDC 2008.

Pour rappel, la Professional Developers Conference est organisée par Microsoft et permet d'avoir un avant-gout des produits et technologie que nous utiliserons demain. A titre d'exemple, cette année, cela parlera de:

  • La plateforme "Live Developer"
  • "Cloud Computing"
  • "Visual Studio 10" et le Framework .NET 4.0
  • ASP.NET Futures incluant la V.Next de MVC, Ajax et Dynamic data
  • Silverlight Futures, incluant "Silverlight for business applications"
  • Et bien plus encore !

Bref, si vous voulez vraiment être en avance de phase, savoir ce qu'il existera et sera mis à la disposition des développeurs de demain, alors c'est l'évènement à ne pas manquer !

Pour cela, une seule URL: http://www.microsoftpdc.com/Registration/

Et pour ceux qui veulent voir un avant-gout des sessions qui seront présentées, c'est par là: http://www.microsoftpdc.com/Agenda/Sessions.aspx

Il est tout de même important de rappeler que la PDC aura lieu du 27 au 30 Octobre 2008 à Los Angeles (Convention Center) et que le keynote sera donné par Ray Ozzie : j'y participerais bien volontier moi Smile

 

A+

[Silverlight] Conférence Silverlight 2, le 19 Juin 2008 à Paris

Vous êtes développeur, chef de projet, architecte, etc. et vous voulez en savoir plus sur Silverlight 2 ? Alors un seul rendez-vous: la Conférence Silverlight 2 organisé le 19 Juin prochain à Paris.

Microsoft, en partenariat avec Epitech, a le plaisir de vous convier à une journée à la fois théorique mais également pratique! Ainsi, voici le programme:

  • Le matin: L´objectif de cette matinée théorique agrémentée de démonstrations d´applications et de code est de:
    • Comprendre les limitations de Silverlight 1.0, qui peut uniquement être programmé en JavaScript
    • Et d´appréhender les apports de Silverlight 2 tant en termes de puissance et d´ouverture, via l´exécution de code .NET managé, que par la présence de contrôles extensibles et supportant le data-binding. Ou encore les mécanismes avancés permettant le multi-linguisme des IHM et les rendant accessibles

 

  • Après-midi: Après avoir compris et assimilé les concepts clé du fonctionnement de Silverlight 2, nous vous invitons à mettre vos acquis en pratique autour de deux ateliers techniques.
    • Un premier workshop vous permettra de découvrir pas à pas les différents aspects de Silverlight 2
    • Ce premier workshop sera suivi d´un second qui vous proposera de créer et de mener à bout un projet en Silverlight 2, utilisant la plupart des techniques de développement clé en Silverlight.

La journée sera animée par le duo de choc Wink :

De plus, si vous avez la possibilité de voir le projet d'un groupe d'étudiants de l'école, je pense que vous serez vite convaincu de la puissance et de l'efficacité de Silverlight 2. En effet, pour les aider (en répondant à leurs questions, en leur donnant des conseils, etc...) sur leur projet, je peux vous garantir qu'il en vaut la peine ! Mais je ne vous en dis pas plus pour le moment, vous devriez en savoir plus le moment venu....

Bref, pour plus d'informations (inscriptions, détails, informations pratiques, etc.), il n'y a qu'une seule adresse et c'est ici: Conférence Silverlight 2 !

 

A+

[.NET] Présentation des "Client Application Services"

Implémenter un système d'authentification et d'autorisations, dans une application Windows/WPF, n'a rien de bien compliqué mais nécessite, mine de rien, du travail supplémentaire.

Depuis ASP.NET 2.0, toute cette architecture existe de façon "pré-configurée" pour les appliations Web: vous crééez une base de données utilisée par ASP.NET pour gérer les utilisateurs et vous disposez d'une interface Web pour créer des utilisateurs, des rôles, ajouter des utilisateurs à ces rôles, etc....

Il est regrétable de voir que ce mécanisme n'existe que pour les applications Web et non pas pour les applications Windows. Enfin, jusqu'à l'arriver du Framework .NET 3.5 et d'une fonctionnalité dont on a très peu entendu parlé: les "Client Application Services".

Ces services permettent aux application Windows d'accéder facilement aux services de login, de profile et de rôles disponibles avec ASP.NET. Autrement dit, ces services vous permettent d'authentifier vos utilisateurs et de récupérer leurs informations (rôles, etc...) depuis un serveur Web.

Comment ca marche ? Tout simplement grâce à des services (d'authentification et d'autorisation) AJAX exposés par une application Web !

Pour que cela soit plus simple, nous allons voir ensemble les différentes étapes pour mettre en place un tel système.

 

Tout d'abord, il nous faut une base de données dans laquelle on va enregistrer les utilisateurs et les rôles. Pour cela, rien de plus simple: l'utilitaire aspnet_regsql.exe (situé dans le répertoire (C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\) fait déjà tout le travail pour nous:

image

Ensuite, nous allons devoir créer un site Web, qui servira pour les authentifications et les autorisations. Pour cela, crééez un site Web qui soit "AJAX Compliant" et ouvrez le fichier web.config. Commencez par rajouter une chaîne de connexion vers votre serveur SQL et, plus précisément, vers la base de données que vous avez configuré précédemment:

image

Ensuite, changez le mode d'authentification de l'application. Par défaut, cela cela utilise l'authentification Windows intégré mais nous, nous allons choisir l'authentification par formulaire, celle qui permet de saisir un couple login/mot de passe pour se connecter:

image

A présent, ajoutez un bloc "Membership" afin de configurer l'application pour utiliser la base de données:

image

Maintenant, ajoutez un bloc "roleManager", comme précédemment:

image

Grâce à ces opérations, votre site Wen est configuré pour utiliser les rôles et tout le reste. Cependant, une application Windows ne peut pas utiliser ces services directement: nous allons devoir les exposer grâce à de l'AJAX. Pour celà, rajoutez ce bout de code dans le fichier:

image

Maintenant, il ne reste plus qu'à créer des utilisateurs et des rôles. Pour cela, rendez-vous dans l'outil d'administration du site Web et ccréez 2 utilisateurs (admin, user) et 2 rôles (Admin, Employee):

image

image

image

Toute la partie "configuration" est à présent terminée. Il ne vous reste plus qu'à utiliser ces services dans une application Windows. Pour cela, créez une application Windows ou WPF et, dans les propriétés, sélectionnez l'onglet "Services" puis cochez la case à coté de "Enable client application services":

image

Ensuite, assurez que "Use Forms authentication" est sélectionné puis, dans les zones de texte suivante, entrez l'URL de votre site Web, qui expose les Web Services:

  • Authentication service location
  • Role service location
  • Web settings service location

Un petit tour dans le fichier app.config vous permettra de voir qu'effectuer ces actions a permis à Visual Studio de créer des noeuds roleManager et Membership, ainsi qu'une clé, dans appSettings, pointant chacun vers le fichier "*_JSON_AppService.axd" correspondant sur le site Web.

A l'utilisation, il vous suffit d'appeler la méthode ValidateUser, en lui passant en paramètres le login/mot de passe, pour que l'application se "branche" sur les services d'authentification du site Web et vous renvoit l'information sur votre statut de connexion:

image

Une fois authentifié, il vous est possible de tester l'appartenance de l'utilisateur à un rôle donné:

image

Si on le veut, on peut même allez plus loin en exposant, depuis le site Web, des propriétés utilisables dans l'application.

Pour cela, ouvrez le fichier web.config et ajoutez ces lignes, utilisez pour exposer la propriété BackColor:

image

Ensuite, sous le noeud <webServices>, ajoutez cette ligne, qui permet de donner accès, en lecture/écriture, à cette propriété:

image

A présent, retournez dans les paramètres de votre application Windows, sélectionnez l'onglet "Settings" et cliquez sur "Load Web Settings":

image

Dans la fenêtre qui survient, pressez simplement le bouton "Skip Login" (cela est possible car nous avons indiqué que certaines propriétés étaient accessibles aux utilisateurs non loggés):

image

Visual Studio se connectera alors automatiquement au site Web que vous avez indiqué précédemment dans la case "Web settings service location" et remplira la liste des paramètres avec ceux exposés sur le site Web. Ensuite, dans votre code, libre à vous d'utiliser ces paramètres de la manière habituelle:

image

 

 

Comme vous pouvez le constater, ces "Client Application Services" sont très intéressants à mettre en oeuvre. Nous n'avons couvert ici qu'une petite partie du sujet, de quoi faire une bonne introduction, mais je crois savoir que quelqu'un prépare un article plus complet dessus: si le sujet vous (a) intéresse(é), je ne saurais que vous conseiller d'avoir un peu de patience Wink

 

En savoir plus: Client Application Services Overview

 

A+

[WPF] Qu'apporte, en terme de graphics, le SP1 du Framework .NET 3.5 ?

Avec la sortie récente du SP1 (en Beta) du Frameork .NET 3.5, on a pu découvrir quelles étaient les nouveautés offertes pour tout ce qui touche aux "graphics".

Greg Schechter a d'ailleurs écrit tout une série d'articles sur le sujet:

Cependant, cela reste très vague aux yeux de tous. OK, il y a de nouvelles fonctionnalités mais on veut en voir plus !

Pour cela, je vous recommande cette vidéo de David Teitlebaum (Program Manager WPF) dans laquelle il montre des démonstrations des possibilités techniques offertes par ces nouvelles fonctionnalités:

Comme vous pourrez le voir, les démos (qui se situent vers les 5 minutes 30) sont à tomber par terre et la consommation CPU (même sur son quadricoeur Big Smile) est relativement faible. Pourquoi ? Tout simplement parce que tout le rendu (ou presque) est fait via le GPU, autrement dit la carte graphique !

Je vous laisse découvrir cela par vous-même et vous verrez: c'est assez impressionnant......

 

A+

[WPF] Comment et pourquoi créer sa propre "MarkupExtension" ?

Lorsque l'on manipule du XAML, il n'est pas rare de rencontrer des choses comme ceci:

{Binding ...}, {StaticResource ...}, and {RelativeSource ...}

Ces chaînes de caractères, encadrées des signes {}, forment ce que l'on appelle des MarkupExtensions.

Il peut arriver, lors de vos développements WPF, que les fonctionnalités offertes par le XAML ne soient pas suffisantes. Pour pallier à ce problème, la solution est d'écrire la fonctionnalité manquante dans le ode behind. Cela marche très bien mais comment faire si l'on ne veut pas écrire cette fonctionnalité dans le code mais faire le maximum de choses en XAML ? On écrit sa propre MarkupExtension ! Smile

Pour faire cela, il n'y a rien d'extraordainire: il vous suffit de créer une classe qui hérite de MarkupExtension et de surcharger la méthode ProvideValue:

public override object ProvideValue(IServiceProvider serviceProvider)

{

    return "Hello World";

}

Notez que les conventions WPF veulent que le nom de votre extension doit-être XXXExtension mais, dans le code, vous pouvez utitliser simplement XXX: c'est la même chose pour les attributs .NET par exemple (qui se nomme YYYAttribute mais que l'on utilise sous la forme YYY):

<TextBlock Text="{CustomExtension:CalculateSum}" HorizontalAlignment="Center" VerticalAlignment="Center" />

Si vous souhaitez utiliser des paramètres, rien de bien compliquer: il vous suffit de déclarer des propriétés dans votre classe:

public double FirstNumber { get; set; }

public double SecondNumber { get; set; }

 

public override object ProvideValue(IServiceProvider serviceProvider)

{

    if (FirstNumber == 0.0 && SecondNumber == 0.0)

    {

        return "No parameters specify";

    }

    else

    {

        return Convert.ToString(FirstNumber + SecondNumber);

    }

}

Et ensuite, de les utiliser dans votre code XAML:

<TextBlock Text="{CustomExtension:CalculateSum FirstNumber=5, SecondNumber=20}" HorizontalAlignment="Center" 

VerticalAlignment="Center" />

A l'exécution, vous remarquez que l'affichage affiche bien le résultat escompté:

 image

Vous avez sans doute remarquez que la méthode ProvideValue renvoit un object: cela sous-entend que vous pouvez lui faire renvoyer ce que vous voulez (chaîne de caractères, images, entier, etc...). Cependant, dans la majorité des cas, vous connaissez le type que vous souhaitez renvoyer: c'est pourquoi il est bon de le spécifier, sur la classe, l'attribut MarkupExtensionReturnType (qui prend en paramètre le type à renvoyer) qui est utilisé par le parseur XAML à la compilation pour s'assurer que vous assigner un type correct à la propriété sur laquelle l'extension est utilisée:

[MarkupExtensionReturnType(typeof(string))]

Au final, votre classe (le code de votre extension) ressemblera donc à ceci:

[MarkupExtensionReturnType(typeof(string))]

public class CalculateSumExtension : MarkupExtension

{

    public double FirstNumber { get; set; }

    public double SecondNumber { get; set; }

 

    public override object ProvideValue(IServiceProvider serviceProvider)

    {           

        if (FirstNumber == 0.0 && SecondNumber == 0.0)

        {

            return "No parameters specify";

        }

        else

        {

            return Convert.ToString(FirstNumber + SecondNumber);

        }

    }

}

Bon développement à tous !

 

A+

[WPF] Les nouveautés/améliorations apportées par le SP1 de VS 2008 et du Framework .NET 3.5

Maintenant que le SP1 est en bonne voie, on peut commencer à voir les différentes améliorations apportées à tout ce qui touche à WPF. Ainsi, Brad Adams nous en parle un peu plus et nous permet de savoir que l'on a droit à:

  • Des améliorations de performances pour le texte, les graphics, les animations, etc....
  • Une API sur les effets WPF. Ainsi, il sera possible d'utiliser des effets (profitant de l'accélération matérielle) sur n'importe quelle "shape" (composants) => Il va falloir que je creuse ca à l'occasion
  • Le support de l'onglet "Evènements" dans Cider, le designer WPF de Visual Studio (et oui, c'est tout bête mais cela n'était pas dispo...):

  • Le tri par ordre alphabétique des propriétés:

  • La possibilité de faire, plus simplement, du design de formulaire:

  • Un meilleur debugging XAML, qui vous renvoit directement sur la ligne XAML qui est incorrecte (voila qui va faire gagner pas mal de temps Wink):

  • Un nouveau contrôle: le WebBrowser (dans System.Windows.Controls):

  • Un nouveau "BindingGroup", dans System.Windows.Data

 

De son coté, Scott Guthrie nous livre également une liste des nouveauté/améliorations relatives à WPF:

WPF Performance Improvements

.NET 3.5 SP1 includes several significant performance optimizations and improvements to WPF.  Some of the specific graphics improvements include:

  • Smoother animations
  • Hardware accelerated rendering of Blur and DropShadow Bitmap Effects
  • Text Rendering speed improvements - especially with VisualBrish and 3D scenes
  • 2D graphics improvements - especially with z-index scenarios
  • A new WriteableBitmap class that enables real-time and tear-free bitmap updates.  This enables custom "paint"-style applications, data visualizations, charts and graphs that optionally bypass the default WPF 2D graphics APIs.
  • Layered window performance improvements

SP1 also adds support for better data scalability in WPF.  The ListView, ListBox and TreeView controls now support "item container recycling" and "virtualization" support which allows you to easily achieve a 40% performance improvement with scrolling scenarios.  These controls also now optionally support a "deferred scrolling" feature which allows you to avoid scrolling in real time and instead wait until a user releases the scroll thumb (the default scrolling mode in Outlook). This can be useful when scrolling over very large data sets quickly. 

WPF Data Improvements

.NET 3.5 SP1 includes several data binding and editing improvements to WPF.  These include:

  • StringFormat support within {{ Binding }} expressions to enable easy formatting of bound values
  • New alternating rows support within controls derived from ItemsControl, which makes it easier to set alternating properties on rows (for example: alternating background colors)
  • Better handling and conversion support for null values in editable controls
  • Item-level validation that applies validation rules to an entire bound item
  • MultiSelector support to handle multi-selection and bulk editing scenarios
  • IEditableCollectionView support to interface data controls to data sources and enable editing/adding/removing items in a transactional way
  • Performance improvements when binding to IEnumerable data sources

WPF also now exposes hooks that enable developers to write custom panels w/ virtualized scrolling.  We'll be using this support together with the above data binding improvements to build the new WPF datagrid that will be shipping later this year.

WPF Extensible Shader Effects

.NET 3.5 SP1 adds support in WPF for a new shader effects architecture and API that allows extremely expressive visual effects to be created and applied to any control or element within WPF.  These shader effects support blending multiple input compositions together.  What makes them particularly powerful is that WPF executes effects (including custom effects you build yourself) using the GPU - giving you fully hardware accelerated graphics performance.  Like almost everything in WPF, you can also use WPF databinding and animation on the properties of an effect (allowing them to be fully integrated into an experience).

Applying an effect onto a Control is super easy - just set a Control's "Effect" property.  For example, to add a hardware accelerated drop-shadow effect on a button you can use the built-in <DropShadowEffect> on it via either code or XAML:

Which will cause the button to render like so:

Because Effects are extensible, developers can create their own custom Effect objects and apply them.  For example, a custom "DirectionalBlurEffect" could be created and added to a ListBox control to change its scroll appearance to use a blur effect if you rapidly scroll across it:

Keep an eye on Greg Schechter's blog to learn more about how the Effects architecture works and to learn how you can both create and apply new effects within your applications. 

Note: In addition to introducing the new Shader Effects API, WPF in SP1 also has updated the existing Blur and DropShadow Bitmap effects already in WPF to be hardware accelerated.

WPF Interoperability with Direct3D

.NET 3.5 SP1 adds support to efficiently integrate Direct3D directly into WPF.  This gives you more direct access to the hardware and to take full advantage of the Direct3D API within WPF applications.  You will be able to treat Direct3D content just like an image within an application, as well as use Direct3D content as textures on WPF controls. 

For example, below are three samples from the Direct3D SDK:

We could either load them in as image surfaces within a WPF application, or map them as textures on WPF controls.  Below is an example of mapping them as textures onto cubes in a WPF 3D application:

Note: the Direct3D integration isn't today's SP1 beta release.  It will appear in the final SP1 release.

VS 2008 for WPF Improvements

VS 2008 SP1 includes several significant improvements for WPF projects and the WPF designer.  These include:

  • Several performance improvements
  • Events tab support within the property browser
  • Ability to sort properties alphabetically in the property browser
  • Margin snaplines which makes form layout much quicker
  • Better designer support for TabControl, Expander, and Grid
  • Code initiated refactoring now updates your XAML (including both control declarations and event declarations in XAML)
  • Go to Definition and Find All References now support things declared in XAML

The debugger has also been updated in SP1 so that runtime errors in XAML markup (for example: referencing styles, datasources and/or other objects that don't exist) will now be better identified within the debugger:

Je sens que la fonctionnalité "StringFormat", utilisable lors du binding, va plaire à beaucoup de monde car elle permet de formatter l'affichage lors du binding: plus besoin de passer par un Converter Wink:

Text="{Binding ElementName=slider, Path=Value, StringFormat='Amount: {0:C}'}"

 

Comme vous pouvez le voir, donc, pas mal de nouveautés et encore, je n'ai couvert ici que la partie WPF: il reste ce qui touche au Web, à ClickOnce, aux langages C#/VB.NET, etc.....

 

Pas mal de choses à tester/jouer avec pour vous en dire plus donc !

 

A+

[.NET] La première Beta du SP1 de VS 2008 et du FX 3.5 est disponible !

Je suis surpris de ne pas encore avoir vu passer l'info sur les blogs de CodeS-SourceS mais bon, week-end prolongé oblige je suppose Smile

Quoi qu'il en soit, Microsoft vient de mettre en téléchargement la première Beta du SP1 de Visual Studio 2008 et du Framework .NET 3.5, à cette adresse: http://msdn.microsoft.com/fr-fr/vstudio/products/cc533447(en-us).aspx

Soma Somasegar nous en parle sur son blog:

Today we released a Beta of Visual Studio 2008 and .NET Framework 3.5 Service Pack 1. 

Traditionally our service packs address a range of issues found both through customer and partner feedback as well as our own internal testing.  While this service pack holds true to that theme and delivers updates for these types of issues, it also builds on the tremendous value that Visual Studio 2008 and .NET Framework 3.5 deliver today and enables an improved developer experience by adding a number of additional components that cover a range of highly requested customer features. For example, the service pack is the first release for Visual Studio 2008 that delivers full support for SQL Server 2008 and the ADO.NET Entity Framework.

La suite ici: http://blogs.msdn.com/somasegar/archive/2008/05/12/visual-studio-2008-and-net-fx-3-5-sp1-beta-available-now.aspx

Au programme, pas mal d'amélioration/nouveautés/correction de bugs !

Attention, cette version ne supporte pas les Silverlight Tools Beta 1 donc pas de Silverlight avec cette version du SP1 mais heureusement, Microsoft devrait mettre à disposition, dans très peu de temps, les Silverlight Tools Beta 2 for Visual Studio 2008 SP1 !

Voir ici pour plus de détails: http://blogs.msdn.com/webdevtools/archive/2008/05/12/error-installing-visual-studio-2008-sp1-beta-and-silverlight-tools-beta-1.aspx

Je ne dirais qu'une chose: à vos VPCs pour tester tout cela Wink

 

A+

[Silverlight] Un petit test de débugging Silverlight vous tente ?

Si la réponse à cette question est oui, alors je ne peux que vous conseiller d'aller sur le blog de Jesse Liberty. En effet, il a posté un petit concours pour tout ceux qui veulent tester leur compétences en terme de débugging.

Comme vous le verrez, cela n'a rien de bien compliqué mais la problématique est intéressante. De plus, Jesse promet de mettre à disposition une vidéo dans laquelle il corrige le bug et explique le "pouquoi du comment" Wink

Pour en savoir plus, c'est par ici: http://silverlight.net/blogs/jesseliberty/archive/2008/05/01/silverlight-debugging-challenge.aspx

 

A+

[WPF] Comment récupérer la valeur d'un attribut personnalisé lors du DataBinding ?

J'ai répondu récemment à une question, sur les forums de Developpez.com, qui était forte intéressante et qui valait bien un petit post sur mon blog.

Pour faire simple, le demandeur était dans le cas suivant:

  • Une listbox liée à une liste de personne
  • Un attribut personnalisé sur les propriétés de la classe Person

Son besoin était simple: il voulait pouvoir afficher, lors d'un binding, la valeur d'une des propriétés de l'attribut personnalisé. En terme de code, nous avions donc ceci:

public class Person

{

    [PersonProperties("LastName : ")]

    public string LastName { get; set; }

 

    [PersonProperties("FirstName : ")]

    public string FirstName { get; set; }

}

 

public class PersonCollection : ObservableCollection<Person>

{

}

 

[global::System.AttributeUsage(AttributeTargets.Property, Inherited = false, AllowMultiple = true)]

sealed class PersonPropertiesAttribute : Attribute

{

    public string Header { get; private set; }

 

    public PersonPropertiesAttribute(string header)

    {

        this.Header = header;

    }

}

Il faut à présent remplir notre collection de personne, par exemple lors du chargement de la fenêtre:

private void Window_Loaded(object sender, RoutedEventArgs e)

{

    ObjectDataProvider odp = this.TryFindResource("PersonCollectionDS") as ObjectDataProvider;

 

    if (odp != null)

    {

        PersonCollection pc = odp.Data as PersonCollection;

 

        if (pc != null)

        {

            pc.Add(new Person() { LastName = "LEBRUN", FirstName = "Thomas" });

            pc.Add(new Person() { LastName = "SANTIN", FirstName = "Florent" });

            pc.Add(new Person() { LastName = "SENTENAC", FirstName = "Philippe" });

            pc.Add(new Person() { LastName = "FURUTA", FirstName = "Mitsuru" });

        }

    }

}

Maintenant, il faut faire en sorte que, lors du binding, on arrive à accéder à l'attribut "PersonProperties" (et à sa valeur) et à l'afficher. Pour cela, il faut déjà mettre en place le binding, en utilisant un convertisseur auquel on va passer un paramètre:

<TextBlock HorizontalAlignment="Right" Margin="0,17,8,0" VerticalAlignment="Top" Width="126" Height="16" Text="{Binding Path=SelectedItem, Converter={StaticResource GetPersonAttributeConverter}, ConverterParameter=LastName, ElementName=lbPersons, Mode=Default}" TextWrapping="Wrap" x:Name="tbLastName"/>

<TextBlock HorizontalAlignment="Right" Margin="0,52,8,0" VerticalAlignment="Top" Width="126" Height="16" Text="{Binding Path=SelectedItem, Converter={StaticResource GetPersonAttributeConverter}, ConverterParameter=FirstName, ElementName=lbPersons, Mode=Default}" TextWrapping="Wrap" x:Name="tbFirstName"/>

Comme vous pouvez en douter, toute la magie va se passer dans le convertisseur, qui va tout simplement faire un peu de reflection sur l'objet passé en paramètre (un objet de type Person) et accéder aux attributs personnalisés:

public class GetPersonAttributeConverter : IValueConverter

{

    #region IValueConverter Members

 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

    {

        string result = string.Empty;

 

        if (value != null)

        {

            Person p = value as Person;

 

            if (p != null)

            {

                var properties = p.GetType().GetProperties();