Les nouveautés dans la personnalisation du texte en WPF

23. October 2010 by Regis.NIOX

I- Introduction

          Dans les nombreuses nouveautés du WPF, nous retrouvons une série d’améliorations visuelles ainsi que diverses possibilités de configurations.

Nous verrons qu’elles sont ces améliorations en détails et comment les configurer ou les personnaliser.

Nous commencerons par le mode ClearTypeHint pour l’aspect visuel puis nous verrons les autres nouveautés en ce qui concerne l’amélioration de l’affichage du texte.

 

II- Le mode ClearTypeHint

          Le mode ClearTypeHint permet de lisser les polices et de permettre ainsi un affichage plus net. Nous avons donc la possibilité d’activer ce mode afin d’améliorer la qualité visuelle du texte.

Pour cela nous n’avons besoin que d’activer la propriété « RenderOptions.ClearTypeHint » correctement.

La classe « RenderOptions » nous permettra de contrôler le rendu du ou des objets :

clip_image001

clip_image003

 

III- Le bindable Run

          Dans le WPF 4, un « Run » pourra être binder afin d’éviter certains dysfonctionnements tel qu’un décalage d’une partie d’un texte, ou encore l’apparition d’espaces non voulus.

Un « Run » est un contrôle qui possède les mêmes caractéristiques qu’un « TextBlock » (mais qui ne peut pas être positionné). Pour ce faire nous l’imbriquerons donc dans un « TextBlock ».

Ce contrôle permet grâce à la propriété « Text » de spécifier le texte à afficher.

clip_image005

 

clip_image006

 

IV-Le mode TextFormating

          Le mode « TextFormating » améliore l’affichage des petites polices de caractères. Il est rattahcé à la propriété « textOptions » (il s’agit d’une classe qui permet de contrôler le comportement du rendu texte grâce à une série d’options).

Nous avons le choix entre deux propriétés pour ce mode :

· Ideal : il s’agit du rendu texte par défaut.

· Display : il s’agit du mode qui permet d’améliorer la qualité de l’affichage du texte (le texte sera plus propre une fois affiché)

clip_image007

 

clip_image009

 

V- SelectionBrush et SelectionOpacity

          Les propriétés « SelectionBrush » et « SelectionOpacity » peuvent être utilisées pour des TextBox, Rich TextBox, FlowDocumentPageViewer, FlowDocumentScrollViewer, FlowDocumentReader et PasswordBox.

La propriété SelectionBrush sert à définir la couleur du surlignement du texte. Nous pourrons également changer, si nous le désirons, le gradient du surlignage.

La propriété SelectionOpacity sert simplement à définir l’opacité du surlignage. En ce qui concerne l’étalonnage de l’opacité, avec une opacité de 1 nous ne verrons plus le texte.

· SelectionBrush :

clip_image010

clip_image011

· SelectionOpacity :

clip_image013

clip_image014

 

VI-Le CaretBrush

          Le CaretBrush est une propriété qui permet de changer la couleur du curseur d’insertion (la tickbar qui est par défaut noire). Cette propriété peut être utilisée sur une « TextBox », « RichTextBox », et une « PasswordBox » :

clip_image015

clip_image016

 

VII-Conclusion

          Ces petites nouveautés en ce qui concerne l’affichage peuvent s’avérer très utile lorsque nous avons besoin de manipuler du texte. Cela permet d’éviter certains dysfonctionnements d’affichage.

Ainsi, avec le WPF 4, nous pouvons maintenant aussi personnaliser certains petits détails tels que la tickbar ou encore la couleur ou même l’opacité d’un sur lignage, afin de personnaliser au maximum notre

application.

WPF, Visual Studio 2010

Utilisation des styles en WPF

11. September 2010 by Yan.GUITTEAUD

Qu’est ce que les styles en WPF

Les styles en WPF sont utilisés pour modifier toute la partie visuelle d’un contrôle tel que sa couleur d’arrière-plan, la couleur de sa police, sa taille…). La classe System.Windows.Style contient une collection de Setters (System.Windows.Setters) qui permet d’assigner les valeurs des dependency property (les propriétés) du contrôle concerné. Les styles peuvent être appliquées à un contrôle, une fenêtre ou à une application.

Tout d’abord nous allons commencer par un exemple ou on spécifie les mêmes valeurs à 3 boutons et 1 label. Le code Xaml résultant est comme ceci :

 Si on veut modifier ce style, il faudra repasser sur ces 3 boutons et ce label afin d’harmoniser nos contrôles. Cela devient vite ennuyant dans le cas d’une application. La meilleure solution serait de factoriser ce code afin de le centraliser d’un côté et y faire référence avec nos contrôles.

C’est ce mécanisme que WPF nous propose avec les styles. Nous allons donc modifier notre code xaml afin que nos contrôles fassent référence à un style.

 

Nous avons déclaré la balise « Window.Ressources » afin de spécifier les ressources dont nous aurons besoin dans notre fenêtre. Ensuite on a utilisé notre b alise « Style » et l’attribut « x:Key » ; afin de donner un nom à notre style. Puis on utlise la collection de « Setters » afin d’affecter des valeurs à chaque propriété de nos contrôles. On utilise la balise « Property » pour spécifier le nom de la propriété à modifier et la balise « Value ». Dans notre cas ci-dessus, tous nos contrôles ne sont pas les même (3 boutons et un label) nous faisons donc référence à des propriétés communes pour ces contrôles. « Control.NomDeLaPropriété » car ces 2 types de contrôles héritent de la classe « Control ». Si nous n’avions que des boutons, nous l’aurions remplacée sans en être obligé par « Bouton.NomDeLaPropriété ».

Visuellement voici ce que ce style nous donne :

Créer des styles pour les appliquer à des contrôles hétérogènes devient alors très facile. Toutefois on peut remarquer que sur notre image le label n’a pas de bordure en rouge. Cette différence provient du fait que les contrôles n’ont pas tous les mêmes valeurs de propriété par défaut. L’épaisseur de la bordure des boutons est à 1 alors que celle du label est à 0. Concrètement, si on veut que notre label respecte entièrement notre style, il nous faudra soit spécifier cette épaisseur à son niveau ou au niveau du style.

Il est évidemment plus pratique de l’appliquer au niveau de notre style comme ceci :

 

Nous obtiendrons cela :

 

Les propriétés qui ne pourront être appliqué à certains contrôles seront ignorées sans lever d’exception. Ceci permet d’éviter de se soucier à savoir si notre contrôle possède cette propriété ou pas.

 

Compléter nos styles

 

Avec le style que nous venons de créer, nous pouvons en créer un autre qui se base sur celui-ci :

En utilisant la balise « BasedOn » nous pourrons compléter ou redéfinir notre style dans un autre. Nous avons rajouté un label pour voir la différence :

 

Nous voyons très clairement que la police de notre label est en gras, est plus petite que les autres et est situé en bas à gauche du label. Style pour un type Enfin, nous pouvons définir nos styles pour n’affecter qu’un type de contrôle en particulier. Pour cela, on utilise la balise TargetType. Je vais juste rajouter cette propriété aux deux s tyles d’avant tout en retirant l’attribut « BasedOn » qui ne permettrait pas de spécifier le type car il serait déjà définit dans notre style de base.

 

 

Si nous essayons désormais d’appliquer le premier style à un label. Visual Studio nous spécifiera que ce n’est pas possible car le type du contrôle n’est pas un bouton. Evénement pour des styles. La définition des styles ne se limitent pas uniquement aux valeurs des propriétés. Il existe une classe dérivée des Setters qui s’appelle EventSetter et qui permet d’attacher un gestionnaire d’événement à un contrôle.

 

Ainsi tous nos labels appelleront Label_MouseEnter lorsque l’événement MouseEnter est déclenché.

Conclusion

Les styles jouent un rôle prépondérant dans la définition visuelle de nos contrôles. On peut les appliquer à tout type de control dans la mesure où leurs propriétés soient communes.

WPF ,

WPF - Animations sous Expression Blend

10. September 2010 by Lo�c.GRISPINO

Introduction


Bonjour,

Tout au long de cet article, vous allez apprendre les animations en WPF. Pour cela, je me suis basé sur le précédent article :


Ce qu’il va nous falloir :

-         Le projet de la fenêtre de notification : Window_Notif.zip (83,36 kb)

-         Expression Blend ( dans ce tutorial j’utilise Expression Blend 4, mais c’est exactement le même principe avec la version 3. )

-     Visual Studio


Une simple animation


Donc, nous nous sommes arrêté à une simple fenêtre qui apparaît et disparait au bout de quelques secondes.


Ce serait quand même beaucoup mieux si tout ceci était animé !


Pour commencer on ouvre le projet dans Expression Blend. Donc comme d’habitude :

File -> Open Project/Solution

Et on lui donne le .sln, exactement comme dans Visual Studio.


Dans l’onglet « Projects », il suffit de double cliquer sur la fenêtre à éditer.



A cet endroit, il faut bien penser à sélectionner [Window] avant de cliquer sur le signe + pour ajouter un storyboard.


Sinon vous créeriez une animation uniquement sur le calque choisi.


Donnez un nom à ce storyboard ( « Pop »  par exemple )


A ce moment le cadre deviens rouge pour montrer que ça enregistre les actions, donc évitez de bouger tout n’importe sinon cela risque de voir. Si éventuellement vous souhaitez deplacer un contrôle ( parce qu’il est mal placé par exemple ). Pensez à cliquer sur la petite boule rouge en haut à gauche pour suspendre l’enregistrement.


Le principe est assez simple, à gauche se trouve une timeline. Le curseur est placé à l’instant 0. Comme on veux faire une animation pour l’apparition, il faut qu’au début de l’animation, la fenêtre soit absente, puis arrive en glissant tout en apparaissant.


Ainsi, curseur à 0 ms, on vérifie que c’est toujours [window] qui est sélectionné, on met l’opacité à 0 du Border et on reste appuyé sur la flèche vers le bas jusqu'à ce que la fenêtre soit hors du cadre noir.


Note : Le fait de rester appuyé sur la touche fléchée vers le bas pose des soucis lors des « ctrl+z » en cas d’erreur mais est très précis et évite de décaler la fenêtre.



Note : Le cadre noir est en quelque sorte notre « champ de vision » tout ce qui est hors de celui ne sera pas visible.


Il ne reste plus qu’à se placer à 1s et de remettre la fenêtre en place et l’opacité du Border à 90%.

 

La première animation est finie !


 

Voici la vidéo des actions à faire :



Pensez au plein écran pour une meilleure visiblité !


Ainsi de suite


Nous allons maintenant faire l’animation pour la disparition. Cette étape va être très rapide car il suffit de :

-         Dupliquer le storyboard Pop

-         Renommer Pop_Copy en Depop

-         Inverser


Pour cela un clic droit sur le nom du storyboard nous affiche le menu contextuel.


Voici la manip :




Pensez au plein écran pour une meilleure visiblité !

Lier à l’évènement

Voila, on a nos 2 animations, il faut maintenant leur dire de se lancer lors de l’ouverture et la fermeture de la fenêtre.


Pour cela, il faut aller dans l’onglet « Triggers » ( ou déclencheurs ) en français. Et d’ajouter les évènements.


Par défaut, window.Loaded s’est ajouté avec l’animation Pop dedans. Vérifiez qu’il n’y a bien que cette animation avant de passer à la suite, parce que parfois ça ajoute n’importe laquelle.



Il ne nous reste plus qu’a ajouter l’animation Depop à la fermeture. Il faut donc cliquer sur « +Event », sélectionner le nouveau déclencheur et le remplir ainsi :



Animation à la fermeture


Le souci qu’on a maintenant, c’est que l’animation se fait bien lors de l’ouverture de la fenêtre mais celle de la fermeture n’a pas le temps d’avoir lieu !


C’est à ce moment que ça se complique un peu. Sauvegardez le projet, fermez Expression Blend puis ouvrez le projet dans Visual Studio.


Dans le code XAML ( design ) :


Dans le paragraphe <Window> , ajoutez l’évènement “OnClosing” et donnez lui un nom :

Closing="Window_Closing"



Trouvez le paragraphe :

<Storyboard x:Key="Depop">

[…]

</Storyboard>

 

Il faut ajouter l’évènement Completed pour pouvoir l’utiliser.


<Storyboard x:Key="Depop" Completed="closeStoryBoard_Completed">

 

Le code doit ressembler à ça :

 

 

 Dans le code C# :


Il faut ajouter la variable booléenne qui passera a TRUE quand l’animation sera finie.

private bool closeStoryBoardCompleted = false;

 

 

 


Et ajouter à la suite de notre classe les 2 méthodes qui permettront d’attendre la fin de l’animation avant de fermer la fenêtre.




Voici donc le rendu final :




Pensez au plein écran pour une meilleure visiblité !

Vous pouvez également télécharger l'archive du projet fini : Window_Notif_anim.zip (83,36 kb)

 

Voila, ce tutorial est fini , je vous remercie pour votre interêt et vous souhaite un bon codage.

ADO.NET, C#, Visual Studio 2010, WPF , , , , , , , , ,

WPF - Création d'une fenêtre de notification.

25. July 2010 by Lo�c.GRISPINO

Préambule

Bonjour,

Au cours de cet article, vous allez apprendre à réaliser une jolie petite fenêtre de notification qui apparaitra en bas à droite de votre écran, un peu comme celle de MSN lorsque quelqu'un se connecte.

Pour la rédaction de cet article, j'ai simplement ajouté un bouton dans ma fenêtre Window1 pour faire apparaitre notre notification.

Les utilités d'une telle fenêtre sont, par exemple, signaler une erreur à l'utilisateur ( champs de formulaire mal remplis, problème quelconque ...), afficher une confirmation à l'utilisateur (login réussi, opération effectuée etc ... ). Le but est d'afficher quelque chose sans que l'utilisateur ne soit géné et n'ai à cliquer dessus.

Voici une vidéo du rendu final :

 

Ajout d'une fenêtre

 

Pour commencer, on va créer une nouvelle fenêtre :

Clic droit sur votre projet, puis Add et New Item

 

Puis choississez "Window (WPF)


Ainsi pour faire apparaitre cette nouvelle fenêtre, il vous suffira de mettre cette ligne :

new Window_Notif().Show();

Note :  ShowDialog() nous ferais apparaître une fenêtre modale

Au clic d'un bouton, par exemple, ou lors d'un evènement précis.

 

Mise en forme de la fenêtre


Voici le code XAML de la fenêtre lors de sa création. Donc un simple carré blanc, avec un GRID à l'interieur pour pouvoir placer ses contrôles.

Nous allons donc réaliser un design rapide. J'ai tout d'abord redimensionné la fenêtre avec pour dimensions :

 

Height="160" et Width="300"

 

Bords arrondis et couleur

Pour commencer, nous allons réaliser des bords arrondis. Pour cela, il faut insérer une bordure à l'intérieur de la fenêtre (toujours) et autour du grid, car celui ci n'accepte pas les attribut que nous allons assigner à la bordure.

 

 

Et ensuite, il faut donc faire quelques ajouts :

Concernant la fênetre en elle même :

On permet la transparence ( et par ce fait, il n'y aura pas de bordure ) , on enlève la barre en haut ( agrandir, fermer et rétrécir) et nous choississons un fond transparent ( qui est blanc par défaut)

 AllowsTransparency="True" WindowStyle="None" Background="Transparent"


Concernant la bordure :

 

On veux des angles arrondis ( le coefficient arrondi plus ou moins, une valeur de type 10,10,0,0 aurait juste arrondi les bords supérieurs ), on veux une bordure de 1 pixel, de couleur noire. Puis une opacité de 0.9.

 CornerRadius="10" BorderThickness="1" BorderBrush="Black" Opacity="0.9"

 

Pour le fond, j'ai choisi un dégradé sur ton bleus, je l'ai réalisé sous Expression Blend, mais ce n'est pas compliqué à comprendre le principe, juste un peu plus fastidieux.

        <Border.Background>
            <LinearGradientBrush MappingMode="RelativeToBoundingBox" EndPoint="0.5,1" StartPoint="0.5,0">
                <GradientStop Color="#FFD1D5FF"/>
                <GradientStop Color="#FF919BE4" Offset="1"/>
                <GradientStop Color="#FDF9F9F9" Offset="0.368"/>
            </LinearGradientBrush>
        </Border.Background>

 

Ce qui nous donne ceci en codage et en apparence.

 

 

C'est un design assez simple et peu recherché mais le principal y est.

 

J'ai également un TextBlock pour voir à quoi cela ressembler :

L'utilisation d'un TextBlock au lieu d'un label est due au fait que l'argument TextWrapping n'existe pas pour ce dernier.

<TextBlock Margin="2,43,6,14" Name="textBlock1" TextWrapping="Wrap" TextAlignment="Center" Text="Ceci est une notification."/>

TextWrapping pour le retour à la ligne automatique, et TextAlignment pour le centrer.

 

Apparition et fermeture

 

A l'heure actuelle, notre notification s'ouvre un peu n'importe où et ne disparais pas, nous allons régler cela simplement en modifiant le code behind de celle ci.

 

Emplacement :

On veux la fenêtre en bas à droite de l'écran :

this.Top = SystemParameters.PrimaryScreenHeight - this.Height;
this.Left = SystemParameters.PrimaryScreenWidth - this.Width - 10;

J'ai légèrement décalé vers la gauche pour une meilleure lisibilité.

On la veux toujours au premier plan :

this.Topmost = true;

 

Texte de notification :

Il nous suffit d'ajouter un argument dans le constructeur puis d'assigner la valeur au text du TextBlock

        public Window_Notif(string message)
        {

...

textBlock1.Text = message;

      }

 

Ce qui nous donne cela :

 

Fermeture


Etant donné que la fenêtre n'a plus de bouton "Fermer" il faut donc régler ce détail. Pour ne pas gêner l'utilisateur lors de l'apparition du cadre, nous allons faire en sorte quelle se ferme toute seule au bout de quelques secondes, qu'elle reste ouverte quand on met le curseur dessus, et qu'elle se ferme quand on clic dessus.


Mise en place du timer

Le timer en question sera de type "DispatcherTimer"

Nous l'initialisons en dehors du constructeur :

DispatcherTimer messageTimer = new DispatcherTimer();

puis, à la fin de notre constructeur, nous choisissons le temps avant l'action et nous lançons le timer. J'ai choisi 3 secondes pour pouvoir lire le message.

 

messageTimer.Tick += new EventHandler(messageTimer_Tick);
messageTimer.Interval = new TimeSpan(0, 0, 0, 0, 3000);
messageTimer.Start();

 

Il nous reste donc à determiner l'action à faire lors du "tick" du timer. Donc, en l'occurence, toutes les 3 secondes.

 

void messageTimer_Tick(object sender, EventArgs e)
{
//Il faut stopper le timer sinon il continue toujours.
messageTimer.Stop();
this.Close();
}

Voila, le timer se ferme tout seul au bout de 3 secondes.

Votre code devrais donc ressembler à cela :

 

 

Actions avec la souris

 

Il nous faut alors récuperer les évènements de la souris pour fermer ou, au contraire laisser la fenêtre ouverte.

 

Dans la partie design :

On ajoute des paramètres à la suite des caractériques de notre fenêtre ( dans notre <Window > )

 

MouseEnter="MouseIn" MouseLeave="MouseOut" MouseLeftButtonDown="WindowClicked"

 

Retour dans le code behind :

On code les méthodes que nous avons nommées juste avant.

 

private void MouseIn(object sender, MouseEventArgs e)
{
    messageTimer.Stop();
}

private void MouseOut(object sender, MouseEventArgs e)
{
    messageTimer.Start();
}

private void WindowClicked(object sender, MouseButtonEventArgs e)
{
    this.Close();

}

 

Utilisation

Maintenant que tout est paramétré, un simple appel du constructeur avec .Show() fera apparaître la fenêtre.

new Window_Notif("Voici un exemple de notification ! ").Show();

 

Aller plus loin

On peux bien sûr beaucoup améliorer cette fenêtre en ajoutant des animations à l'ouverture ET à la fermeture ( plus compliqué ) faites à l'aide de Expression Blend. Et également modifier le constructeur pour prendre en argument un booléan qui determinera si le message est une erreur ou un simple message.

Voici une petite vidéo pour vous montrer ce qu'on peux faire.

 

Vous pouvez télécharger le projet fini : Window_Notif.zip (83,36 kb)

Je vous remercie pour votre interêt et vous souhaite un bon codage !


ADO.NET, C#, Visual Studio 2010, WPF , , , , , , , , , , , , ,

Deployer et lancer un jeu XNA 4.0 sur émulateur WP7 sans visual studio.

8. June 2010 by Thomas.Trentin

 

Deployer et lancer un jeu XNA 4.0 sur émulateur WP7 sans visual studio.

1 . Pré-requis:

 

XNA Game Studio 4.0.

CTP April Refresh (Visual Studio 2010 Express For Windows Phone) .

 

Ce tutorial a pour but de vous montrer comment déployer un programme XNA 4.0 sur l'émulateur Windows Phone 7 de microsoft (fournit avec la April Refresh), sans avoir nécessairement le code sous la main.

Ceci peut ête très pratique notament afin de faire tester votre application à une personne tierce sans lui livrer votre code.

 

2 . Deploiement :

 

Créez votre projet XNA 4.0 et compilez le.

Pour une question de simplicité, les fichiers récupérés seront tous mis dans un dossier commun.

Allez dans le dossier de sortie de compilation (dans mon cas bin\Windows Phone\Debug) et récupérez le « .xap » généré, qui est l’archive contenant votre jeu.

Dans mon cas, il s’agit de « XnaGraphicsDemo.xap ».

 

Récupérez aussi le GameThumbNail.PNG.

Allez ensuite dans le dossier : \obj\Windows Phone\Debug et récupérez le fichier « XapCacheFile.xml ».

Il contient les informations sur les ressources et les fichiers de votre application, contenus dans le xap.

 

Enfin, allez dans le dossier properties et ouvrez le fichier AssemblyInfo.cs :

Il faut récupérer la valeur notée sur cette ligne :

Dans notre cas, la valeur à noter est donc : "ba971892-de57-4fa4-b7e6-65d9d6da5af7".

Cela correspond à l’ID de l’application, et est indispensable afin de l’utiliser sur Windows Phone (aussi bien pour le déploiement que pour l’installation).

Vous devez maintenant avoir un dossier contenant tous les fichiers demandés jusqu’ici, ce qui doit ressembler à ceci :

 

Ouvrez maintenant une invite de commande.

Faite glisser le fichier « wp.exe », qui est dans le dossier C:\Program Files (x86)\Microsoft XNA\XNA Game Studio\v4.0\Tools (chemin dépendant de l’installation sur votre machine).

Cela devrait ressembler à ceci :

Tappez maintenant  « install », qui permet de déployer votre application sur l’émulateur, puis faite glisser dans l’invite de commande le fichier « xap », coller le GUID copié précédemment, et enfin faites glisser le fichier thumbail et le fichier xml.

Terminez la commande avec l’instruction « /clean ».

Apuyez sur entrée : l’émulateur se lance et installe votre application automatiquement.

Lorsque le lancement de l’émulateur et l’installation de votre application est terminée, vous devez maintenant avoir l’écran d’accueil d’affiché sur votre émulateur :

 

Vous n’avez plus qu’à taper dans votre invite de commande la ligne comportant le « launch » : (en remplaçant bien sûr la  valeur après le launch par le GUID de VOTRE application) : 

 

Voici le résultat :

C#, Visual Studio 2010, Windows phone 7, WPF, XNA ,

Les nouveautés de WPF 4

13. April 2010 by Romain.FREYBURGER

 

Qu’est ce que WPF ?

 

Windows Presentation Foundation, plus couramment nommé WPF  est un sous-système graphique pour le rendu des interfaces utilisateur dans les applications Windows.

 Précédemment connu sous le nom «Avalon», WPF fut développé dans le cadre du Framework .NET 3.0. Il  est basé sur DirectX, supportant ainsi l'accélération matérielle et des fonctionnalités d'interface modernes comme la transparence et les dégradés.

WPF offre également un nouveau langage basé sur XML, le XAML (eXtensible Application Markup Language), permettant ainsi de séparer clairement l’interface utilisateur et la logique métier, partageant de ce fait le travail du designer et du codeur.

Finissons par dire qu’une application WPF peut tout aussi bien être déployé sur le bureau ou hébergées dans un navigateur Web et que sa nouvelle version, WPF 4 sort aujourd’hui, le 12/04/2010.

 

Ce qu’apporte WPF 4

 

Plusieurs années se sont écoulées depuis les débuts de WPF, ce qui en fait une technologie de plus en plus mature, et de ce fait de plus en plus apte à s’attaquer à des applications métier. C’est en partie sur ce point qu’est axé WPF4, en test depuis quelques mois et désormais disponible au grand public. S’adaptant à Windows 7, cette nouvelle version de WPF apporte de nombreuses avancées concernant l’optimisation et la prise en main pour les développeurs.

Première des nouveautés abordées, l’affichage du texte. En effet, avant WPF 4, on pouvait rencontrer des problèmes de lisibilité des textes, quand ceux-ci étaient écrits en trop petit par exemple.  On comprend donc l’arrivée de ClearTypeHint qui améliore l’affichage de Cleartype, et permet donc un meilleur affichage à l’écran grâce à  une option de lissage des polices.

On remarquera l’arrivée d’une propriété arrivant directement de Microsoft Silverlight : LayoutRounding qui agit au niveau des contrôles. Cette dernière  évite le flou que l’on pouvait remarquer sous WPF 3.5 et ses prédécesseurs.

Les animations sont désormais optimisées grâce à un traitement toujours inspiré de Silverlight. L’une des nouveautés sont les « Easing Animations » permettant de « jouer » avec les accélérations/décélérations, rendant les animations plus naturelles, plus fluides et surtout plus simple à implémenter pour le codeur.

D’autres innovations directement inspirés de Silverlight apparaissent comme Visual State Manager, qui permet de gérer différents états visuels au niveau des contrôles ou encore Cached Composition. Ce dernier permet quant à lui de mettre en cache les éléments de l’interface graphique sous forme de bitmap. Le rendu d’une image étant bien plus rapide qu’en temps normal, cela apporte un gros avantage. Un inconvénient en ressort néanmoins, il faudra se méfier des zooms. Vous l’aurez compris, suite à un important grossissement, la qualité d’une image est bien inférieure à celle d’un rendu vectoriel.

Nous l’avons vu et Microsoft l’a clairement annoncée, avec WPF 4 arrive la volonté de se rapprocher du Silverlight et donc des applications web qu’elles soient online ou out of browser.

Beaucoup les attendaient, de nouveaux contrôles comme Datagrid, Calendar ou encore DatePicker sont désormais nativement intégrés. En effet, ceux-ci n’existaient que dans le WPF toolkit mis à disposition par Microsoft et sont dorénavant plus facilement accessible.

 

L’environnement de développement a  également grandement évolué dans le sens des fonctionnalités avec l’arrivée d’un éditeur de ressource et de binding directement intégré, l’amélioration du sélectionneur de couleur…

A noter également l’arrivée de Custom Speller Dictionnary, qui démontre de l’avancée attendue dans le domaine de la gestion des dictionnaires. En effet, avant WPF 4, le correcteur de texte de WPF n’était pas aisément personnalisable. Il suffira désormais d’ajouter un fichier .lex (un simple document texte) à notre application pour enrichir notre dictionnaire.

Une grosse amélioration arrive également au niveau du Binding. Avant WPF 4, la propriété Command n’était pas une DependencyProperty, il était alors impossible de binder. Désormais avec WPF4, Command, Key et Modifiers sont des DependencyProperties, cela devient donc possible.

On notera également l’arrivée des objets dynamiques que je vous laisse découvrir plus amplement avec l’article suivant : http://www.labo-dotnet.com/post/VB10-et-C-4-les-langages-net-evoluent.aspx

 

Dans cette nouvelle version, WPF 4 s’adapte au nouvel OS en vigueur : Windows Seven. Première innovation présentée : Les Jumplists, c'est-à-dire le panneau qui s’ouvre suite à un clic droit sur une icône de la barre des taches. Une image valant mieux qu’un long discours, une Jumplist, c’est ça :

 

 

Elles sont entièrement et facilement personalisables grâce à une API managée native dans WPF 4.

On peut, par exemple, modifier l’icône dans la barre des taches, ajouter ou supprimer des éléments ou des applications.

WPF 4 ne serait pas complet sans la gestion du Multitouch. C’est donc tout naturellement que cette technologie est intégrée de manière native et applicable à tous les UIElements grâce à une API de gestion du tactile.

 

Finalement, nous pouvons résumer cette nouvelle version de WPF en 3 mots : Innovation, Amélioration et optimisation.

 

 

C#, Visual Studio 2010, WPF

Utiliser une API PHP en C#

1. April 2010 by Thomas.Trentin

Tutoriel : Utiliser une API PHP en C#.               

 

Sommaire :

- La classe WebClient,

- Méthodes utilisées,

- Récupérer une page web simple,

- Utilisation avec une API PHP,

- Utiliser UserState pour des traitements plus complexes

 

1.  La classe WebClient

 

définition MSDN :

« Fournit des méthodes communes pour envoyer et recevoir des données venant d’une ressource identifiée par URI. »

 

Comme la définition l’explique, un object WebClient peut être utiliser pour envoyer/recevoir des donnés, uploader ou télécharger des fichiers etc.

La plupart des methods de la classe ont un equivalent asynchrone (par exempe, UploadString à pour equivalent aynchrone UploadStringAsync). Cela peut se révéler très utile en cas de mauvaise connexion internet par exemple. En effet, tandis qu’une action synchrone bloque l’application, ce n’est pas le cas d’une opération asynchrone.

 

Voici l’espace de nom où se trouve notre classe WebClient :

 

CODE :    using System.Net;

 

 

Et voici la manière d’en instancer un nouveau :

 

CODE :    WebClient client = new WebClient();

 

 

Pour plus d’informations, reportez-vous à cette page MSDN.

 


 

2.     Méthodes utilisées pour notre tutoriel

 

Le but de ce tutoriel va être, afin de mieux vous expliquer l’utilité de WebClient, de récupérer des données à partir d’une API coté serveur (typiquement PHP ou ASP .NET). Nous allons ici simplement voir comment recevoir les données. Il sera de votre ressort de faire, coté serveur, le nécessaire pour envoyer les bonnes données.

 

En cherchant dans les méthodes disponibles pour notre classe WebClient, nous pouvons voir qu’il y a deux méthodes particulières de récupération de données qui correspondent à nos besoins :

-         DownloadString,

-         DownloadStringAsync.

 

Comme expliqué précédemment, DownloadString fait exactement la même chose que DownloadStringAsync, mais de manière synchrone.

 

Voici les prototypes de nos méthodes :

String DownloadString( [string|URI] );

Void DownloadStringAsync( URI [,object]);

 

DownloadString requête le serveur spécifié au travers des parameters envoyés (qui peuvent être une chaine, ou une URI), attend la réponse, et retourne une chaine de caractères. Donc si la requête prend beaucoup de temps à être traité par le serveur, votre application sera bloqué pendant ce temps.

DownloadString Async, lui, appelle le serveur spécifié en paramètre (qui doit être une URI), et attend la réponse dans un autre processus. Donc l’application n’est pas bloquée, même si la réponse n’est pas instantanée.

 

Une fois que la requête a été effectuée, nous devons créer une method qui va traiter le résultat.

Nous allons cette fois-ci utiliser l’événement de notre classe : DownloadStringCompleted

CODE : client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(   void (object, DownloadStringEventArgs) target  );

 

La méthode qui traitera la requête est de type void, et prend deux arguments (un object et un DownloadStringCompletedEventArgs).

Voici un exemple :

CODE:

WebClient apiClient = new WebClient();

          apiClient.DownloadStringCompleted += new DownloadStringCompletedEventHandler(apiClient_DownloadStringCompleted);

 

// sender = WebClient qui a appellé la méthode

// e contient le résultat de la requête

void apiClient_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

{

     …

}

 

 

Lorsque l’application recevra la réponse du serveur, la méthode apiClient_DownloadStringCompleted sera appelée.

De plus, DownloadStringAsync prend un paramètre optionnel, de type object (vous pouvez donc lui transmettre ce que vous voulez), qui sera disponible dans notre event, via DownloadStringCompletedEventArgs.UserState.

Dans notre exemple, il serait accessible dans  e.UserState.

Nous verrons dans la prochaine partie comment l’utiliser

Exemple complet

 

Maintenant que nous avons comment se servir de notre classe WebClient et de ses méthodes/événements, c’est le moment de pratiquer.

Voici quelques exemples que nous allons réaliser :

-         Récupérer une simple page web,

-         Utiliser une API PHP,

-         Utiliser le UserState pour un usage plus avancé.

 


 

1.     Récupérer une simple page web


Voici l’application la plus simple que l’on puisse faire. Nous allons simplement récupérer la page de campus Booster avec un WebClient.

 

CODE:

 

void LaunchClient()

        {

            WebClient client = new WebClient();

            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

            client.DownloadStringAsync(new Uri("http://www.campus-booster.net/"));

        }

 

        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

        {

            if(e.Result!= string.Empty)

                 MessageBox.Show(e.Result);

        }

 

Si vous testez le code, vous verrez que nous avons bien récupéré le code source de notre plateforme favorite.

 

Ce n’est pas réellement utile pour l’instant, mais cela nous montre ce dont nous allons avoir besoin pour faire un puissant système de requête vers une API.

2.    

      Utilisation avec une API PHP

 

Considérons une page PHP à cette adresse :  http://mysite.com/api.php.

 

Si vous utilisez le code que nous avons vu précedemment, avec ce lien en paramètre, nous recevrons le code venant de notre fichier api.php. Et c’est exactement ce dont nous avons besoin !

 

Voici un exemple de code pour notre fichier api.php

PHP API (api.php) :

 

echo ‘Hello !’;

 

 

 

Si nous faisons une requête sur cette page, nous récupererons “Hello”. C’est un excellent début !

 

Maintenant, imaginons un scenario plus complexe.

Nous appelons l’URI suivante :

http://www.mysite.com/api.php?arg1=10&arg2=20

(Requête GET classique).

 

Nous pouvons faire, coté PHP, les traitements que nous voulons suivant les arguments reçus, et renvoyer une réponse adequate.

Donc, avec un WebClient, il deviant trés simple d’interagir avec une API PHP.

Il est également possible de faire des requêtes en POST, mais ce n’est pas le but de ce tutoriel.


 

3.     Utiliser UserState pour des traitements plus complexes

 

Voici la partie finale de ce tutoriel.

Nous avons appris les méthodes basiques de WebClient, comment récupérer le code source d’une page web, et comment réagir avec une API PHP.

Nous allons à présent rendre notre traitement plus simple dans le code C#, pour nos traitements plus complexes.

 

Pour rappel, voice le prototype de la method DownloadStringAsync :

Void DownloadStringAsync( URI [,object]);

 

Jusqu’à maintenant, nous savions simplement qu’il était possible d’ajouter un second paramètre, nous allons cette fois-ci, l’utiliser.

 

Considérons ce code :

CODE:

 

void LaunchClient()

        {

            WebClient client = new WebClient();

            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

            client.DownloadStringAsync(new Uri("http://mysite.com/api.php?arg=whatever"),"test");

        }

 

        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

        {

            if(e.Result!= string.Empty)

                 MessageBox.Show(e.Result);

           

            MessageBox.Show((string)e.UserState):

 

        }

 

Nous passons la chaine “test” à notre methode.

 

Si nous affichons e.UserState, cela nous marquera bien « test », puisque c’est ce que nous avons stocké dans l’UserState de DownloadStringCompletedEventArgs.

 

Mais cela n’est pas forcément utile.

 

Considérons le code suivant :

CODE:

 

Enum enState

{

    gettingID, gettingInfo, play

}

 

void LaunchClient()

        {

            WebClient client = new WebClient();

            client.DownloadStringCompleted += new DownloadStringCompletedEventHandler(client_DownloadStringCompleted);

            client.DownloadStringAsync(new Uri("http://mysite.com/api.php?arg=whatever"),enState.gettingID);

        }

 

        void client_DownloadStringCompleted(object sender, DownloadStringCompletedEventArgs e)

        {

            //if(e.Result!= string.Empty)

            //     MessageBox.Show(e.Result);

           

            switch ((enState)e.UserState)

            {

                case enState.play:

                    //traitement

                    break;

 

                case enState.gettingID:

                    // traitement

                    break;

 

                case enState.gettingInfo:

                    // traitement

                    break;

            }

        }

 

Nous pouvons donc, maintenant, suivant les informations que nous demandons à l’API, faire different traitements.

 

 

Nous avons vu comment utiliser WebClient, afin de communiquer avec des API serveur, et faire des traitements efficaces dans notre code C#, grâce à l’UserState.

 

C#, WPF

Accès aux données générique avec Linq To SQL et C#

25. February 2010 by Pierre-Luc.ROUAYS

Accès aux données générique avec Linq To SQL et C#

Introduction :

Cet article permet de construire une couche d’accès aux données générique en utilisant LINQ To SQL. Ceci permettra par la suite d’effectuer les opérations basiques du CRUD. Nous créerons une classe nommée EntityCrud qui implémentera ces fonctionnalités.

Vous pourrez par la suite créer des Adapters pour chacune de vos classe dérivant ce cette classe.

 

Place à l’action !

Nous allons créer une simple solution contenant 2 projet : le programme et la couche d’accès aux données (DAL).

 

 

Ajouter un élément de type classe LINQ To SQL :

Puis ensuite ajouter les Tables à votre projet par le biais de l’explorateur de solution.

Code Projet MonProgramme.DAL

La classe EntityCrud contient tout le code nécessaire pour communiquer avec la base de donnée par le biais de LinqToSQL.

Voici la classe AdapterFactory :

 

 

using System;

using System.Collections;

using System.Collections.Specialized;

using System.Collections.Generic;

using System.Collections.ObjectModel;

using System.Linq;

using System.Data.Linq;

using System.Data.Linq.Mapping;

using System.Text;

using System.ComponentModel;  

The next section contains the namespace and class declarations. 

namespace MonProgramme.DAL

{

 

    /// <summary>

    /// Generic Interface to Database

    /// using LINQ to SQL

    /// </summary>

          public class EntityCrud

          {

 

 

Première fonction permettant de récuperer un objet par sa clé Primaire.

               /// <summary>

                   /// Select by Primary Key Value

                   /// </summary>

                   /// <typeparam name="T"></typeparam>

                   /// <param name="id">The PK value to search for</param>

                   /// <returns>Single matching PK to id</returns>

                   public static T SelectByPK<T>(String id) where T : class

                   {

                             try

                             {

                                      using (NWindDataContext context = new

                        NWindDataContext())

                                      {

                              // Récupère la table du type passé

                                                var table = context.GetTable<T>();

 

                              // Récupère le mapping de l’objet avec la Base

                                                MetaModel modelMap = table.Context.Mapping;

 

                              // Récupère les members de l’objet

                              ReadOnlyCollection<MetaDataMember> dataMembers

                              = modelMap.GetMetaType(typeof(T)).DataMembers;

 

                              // Cherche le nom du champ de la clé primaire

                              string pk = 

                              (dataMembers.Single<MetaDataMember>(m =>

                              m.IsPrimaryKey)).Name;

 

                              // Retourne l’objet unique qui correspond à cette clé primaire

                              // passée en argument

                                    return table.SingleOrDefault<T>(delegate(T t)

                                    {

                                    String memberId =

      t.GetType().GetProperty(pk).GetValue(t,

                                    null).ToString();

                                    return memberId.ToString() == id.ToString();

                                    }

      );

                                      }

                             }

                             catch (Exception)

                             {

                                      throw;

                             }

                   }

 

 

Seconde méthode permettant de récupérer toutes les objets de la base.

 

        /// <summary>

        /// Select All by Type

        /// </summary>

        /// <typeparam name="T"></typeparam>

        /// <returns>Matching table as typed list</returns>

        public static IList<T> SelectAll<T>() where T : class

        {

            try

            {

                using (NWindDataContext context = new NWindDataContext())

                {

                    // Récupère la table qui correspond au type

                    // et retourne tous les enregistrement sous forme de liste

                    var table = context.GetTable<T>().ToList<T>();

                    return table;

                }

            }

            catch (Exception)

            {

                throw;

            }

        }

 

Méthode d’insertion de donnée dans la base.

                   /// <summary>

                   /// Insert an Object into a Table

                   /// </summary>

                   /// <typeparam name="T"></typeparam>

                   /// <param name="item"></param>

                   public static void Insert<T>(T item) where T : class

                   {

                             try

                             {

                // Récupère la table du type passé en argument

                // Insert l’enregistrement et soumet les changements à la Base

                                      using (NWindDataContext context = new

                        NWindDataContext())

                                      {

                              // Récupère la table correspondante

                                                var table = context.GetTable<T>();

 

                              // Passe l’objet à la method InsertOnSubmit

                              // et Soumet les changements

                                                table.InsertOnSubmit(item);

                              context.SubmitChanges();

                                      }

                             }

                             catch (Exception)

                             {

                                      throw;

                             }

              }

 

Méthode de mise à jour de donnée.

 

       /// <summary>

                   /// Update an Existing Object

                   /// </summary>

                   /// <typeparam name="T"></typeparam>

                   /// <param name="item">The object to update</param>

                   public static void Update<T>(T item) where T : class

                   {

                             try

                             {

                        // Crée une nouvelle instance de l’objet

                                      Object newObj = Activator.CreateInstance(typeof(T),    

                        new object[0]);

 

                                      PropertyDescriptorCollection originalProps =

                        TypeDescriptor.GetProperties(item);

 

                        // Donne la valeur de la donnée passée en argument à l’objet

                                      foreach (PropertyDescriptor currentProp in

                        originalProps)

                                      {

                                                if (currentProp.Attributes[typeof(

                              System.Data.Linq.Mapping.ColumnAttribute)] !=

                              null)

                                                {

                                                          object val = currentProp.GetValue(item);

                                                          currentProp.SetValue(newObj, val);

                                                }

                                      }

 

                        // Lie l’objet à un nouveau context de donnée

                        // et soumet les changement à la Base.

                                      using (NWindDataContext context = new

                        NWindDataContext())

                                      {

                                                var table = context.GetTable<T>();

                                                table.Attach((T)newObj, true);

                                                context.SubmitChanges();

                                      }

                             }

                             catch (Exception)

                             {

                                      throw;

                             }

                   }

 

Code de suppression d’un objet.

               /// <summary>

                   /// Remove an object

                   /// </summary>

                   /// <typeparam name="T"></typeparam>

                   /// <param name="item"></param>

                   public static void Remove<T>(T item) where T : class

                   {

                             try

                             {

                        // Crée une instance de l’objet avec le type passé en argument

                                      Type tType = item.GetType();

                                      Object newObj = Activator.CreateInstance(tType, new 

                        object[0]);

 

                        // Récupère les proprieties de l’objet passé en argument

                                      PropertyDescriptorCollection originalProps =

                        TypeDescriptor.GetProperties(item);

 

                        // Copie le contenue de la donnée passée en argument

                        // au nouveau objet du meme type

                                      foreach (PropertyDescriptor currentProp in

                        originalProps)

                                      {

                                                if (currentProp.Attributes[typeof(

                              System.Data.Linq.Mapping.ColumnAttribute)] !=

                              null)

                                                {

                                                          object val = currentProp.GetValue(item);

                                                          currentProp.SetValue(newObj, val);

                                                }

                                      }

 

                        //lie l’objet à la table, appel de la function deleteOnSubmit

                        // et soumet les changement à la base.

                                      using (NWindDataContext context = new

                        NWindDataContext())

                                      {

                                                var table = context.GetTable<T>();

                              table.Attach((T)newObj, true);

                                                table.DeleteOnSubmit((T)newObj);

                                                context.SubmitChanges();

                                      }

                             }

                             catch (Exception)

                             {

                                      throw;

                             }

                   }

 

Utilisation :

Une fois l’EntityCrud créé vous pouvez l’utiliser comme dans les exemples suivant :

Exemple Insert :

           try

                             {

                             Customer c = new Customer();

                             c.CustomerID = "AAAAA";

                             c.Address = "554 Westwind Avenue";

                             c.City = "Wichita";

                             c.CompanyName = "Holy Toledo Bibles";

                             c.ContactName = "Frederick Flintstone";

                             c.ContactTitle = "Boss";

                             c.Country = "USA";

                             c.Fax = "316-335-5933";

                             c.Phone = "316-225-4934";

                             c.PostalCode = "67214";

                             c.Region = "EA";

 

                             Order_Detail od = new Order_Detail();

         od.Discount = .25f;

                             od.ProductID = 1;

                             od.Quantity = 25;

                             od.UnitPrice = 25.00M;

 

                             Order o = new Order();

                             o.Order_Details.Add(od);

                             o.Freight = 25.50M;

                             o.EmployeeID = 1;

                             o.CustomerID = "AAAAA";

 

                             c.Orders.Add(o);

 

                             EntityCrud.Insert<Customer>(c); //INSERT Customer mais aussi les autres champs qui lui sont associés (order, order_detail).

 

                             }

                             catch (Exception ex)

                             {

                                      MessageBox.Show(ex.Message);

                             }

 

Les données seront toutes insérée en base : Le Customer, L’order et l’order_detail avec seulement cet appel : EntityCrud.Insert<Customer>(c);

Exemple Delete :

                             try

                             {

                             Customer doa = EntityCrud.SelectByPK<Customer>("AAAAA");

                                     EntityCrud.Remove<Customer>(doa); //DELETE

                             }

                             catch (Exception ex)

                             {

                                      MessageBox.Show(ex.Message);

                             }

Exemple Update :

 

         try

                             {

                                      var q = EntityCrud.SelectByPK<Customer>("AAAAA");

 

                                      q.City = "Calgary";

                                      q.Country = "Canada";

                                      q.Address = "100 Longhorn Drive";

                                      q.CompanyName = "Holy Moses Bibles";

                                      q.Region = "EE";

                                      q.ContactTitle = "Gopher";

                                      q.ContactName = "Moxie Peroxide";

 

                                      EntityCrud.Update<Customer>(q);//UPDATE

                             }

                             catch (Exception ex)

                             {

                                      MessageBox.Show(ex.Message);

                             }

 

ADO.NET, ASP.NET AJAX, C#, WPF , , , ,

Trucs et astuces WPF

Voilà une compilation de divers trucs et astuces WPF récoltés aux quatre coins du web, ainsi que la présentation d’outils et de composant pouvant améliorer grandement le développement de vos applications.

Comportement

Comment se lier à une propriété définie dans les settings ?

Il est bien pratique d’utiliser les Settings disponibles depuis Visual Studio 2005 pour définir des paramètres qui seront accessibles directement depuis le code, après que leur valeur ait été instanciée au démarrage de l’application.

Seulement, on pourrait se demander comment accéder à ces paramètres dans le code XAML et il s’avère que cela n’est pas très compliqué. Après avoir définit vos paramètres:

clip_image001

Il suffit de mapper un namespace XML pointant vers le namespace CLR définissant vos propriétés:

xmlns:properties="clr-namespace:TestSettings.Properties"

Puis, dans votre code XAML, accéder à votre propriété en utilisant la syntaxe suivante:

x:Static properties:Settings.Default

Ce qui donne, au final, un code ressemblant à ceci:

<ListBox x:Name="lb"
ItemsSource="{Binding Source={x:Static properties:Settings.Default}, Path=Names}" />


Simple et efficace.

Auteur : Thomas Lebrun

Site : http://blogs.codes-sources.com/tom/

 

Héritage de la classe Window :

Imaginons que nous avons comme projet de faire une jolie application WPF, avec des fenêtres personnalisées. Problème : on supprime la barre de titre Windows, donc la possibilité de déplacer la fenêtre en la cliquant et la déplaçant. Il faut donc implémenter ce comportement à toutes nos fenêtres.
En windows form, on pouvait très facilement faire une fenêtre mère dont hériterait des fenêtres enfant afin d’avoir par exemple le même comportement.
Mais en WPF, on ne peut pas le faire aussi simplement.

En effet, si on fait hériter notre classe Window1 de notre fenêtre mère MotherWindow dans le fichier Window1.xaml.cs comme ceci :

public partial class Window1 : MotherWindow

Le compilateur va nous retourner une erreur, car l’élément racine du fichier xaml correspondant précise la classe mère dont doit hériter la classe Window1.
Il suffit donc de le changer lui aussi, en définissant aussi un espace de nom dans le fichier xaml :

<local:MotherWindow 
 x:Class="Heritage.Window1"
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:Heritage"
 Title="Window1" Height="300" Width="300">
  <Grid>
  </Grid>
</local:CloseMove>


Sans oublier bien sûr de préciser parmi les espaces de noms que local correspond à notre assembly.

Auteur : Jérémie Bertrand

Site : http://blog.developpez.com/laedit/

 

Comment être notifié (et réagir) lorsqu’une DependencyProperty interne à WPF est modifiée

Lorsque l’on définit ses propres DependencyProperties, on a la possibilité de définir une Callback qui est appelée lorsque la propriété est modifiée.

Cependant, on peut vouloir faire la même chose, au niveau d’un CustomControl, sur une DependencyProperty définie sur l’une des classes disponibles dans le framework WPF (ActualWidthProperty, HeightProperty, etc…)

Pour cela, il est nécessaire d’utiliser la syntaxe suivante:

public MonControl()
{
DependencyPropertyDescriptor.FromProperty(WidthProperty, 
 typeof(MonControl)).AddValueChanged(this, delegate
{
MessageBox.Show("La valeur a été modifiée !");
});
}

Comme vous pouvez le voir, on fait appel à la méthode FromProperty de la classe DependencyPropertyDescriptor qui permet d’accéder au PropertyDescriptor (métadonnées) de la propriété spécifiée (WidthProperty dans notre cas). Ensuite, on appelle la méthode AddValueChanged en lui passant, tout simplement, un délégué vers la méthode qui sera invoquée lorsque la propriété sera modifiée.

Auteur : Thomas Lebrun

Site : http://blogs.codes-sources.com/tom/

 

Comment assigner une ressource dynamique depuis le code-behind ?

Dans le cadre d’un développement WPF, on est très souvent amené à assigner des ressources à des contrôles/composants de l’interface graphique. Lorsque l’on fait cet assignement en XAML, rien de plus simple: il suffit d’utiliser la MarkupExtension StaticResource (ou DynamicResource, si la ressource est amené à être modifiée).

<Button Content="Find Position" Click="Button_Click" Background="{DynamicResource brush}" />

Mais qu’en est-il des cas où l’on souhaite faire ce genre de chose depuis le code behind ? Dans ce cas, il convient d’utiliser la méthode SetResourceReference (http://msdn.microsoft.com/en-us/library/system.windows.frameworkelement.setresourcereference.aspx):

<Window.Resources>
  <SolidColorBrush x:Key="brush" Color="Red" />
</Window.Resources>
<Button x:Name="btn"Content="Find Position" Click="Button_Click" />

this.btn.SetResourceReference(BackgroundProperty, "brush");

Comme vous pouvez le voir, c’est relativement simple à mettre en place: on définit la ressource, on définit le contrôle puis, dans le code behind, on appelle la méthode SetResourceReference en lui passant en paramètres:

  • la Dependency Property sur laquelle on va appliquer la ressource
  • le nom de la ressource

Auteur : Thomas Lebrun

Site : http://blogs.codes-sources.com/tom/

 

 

 

 

Découvrons la collection CompositeCollection

Je dois reconnaitre que j'ai découvert très récemment cette collection mais elle semble être bien pratique.

En effet, la CompositeCollection vous permet de mélanger plusieurs collections et éléments de façon à ce qu'ils soient affichés comme une seule et même liste.

Par exemple, il arrive souvent que l'on rencontre des gens se demandant comment rajouter un élément vide dans une ComboBox qui est bindée à une ObservableCollection. Pour cela, la première idée serait de travailler directement sur l'ObservableCollection utilisée comme source de données.

L'autre technique est de passer par cette fameuse CompositeCollection soit:

<ComboBox x:Name="TheCombo" DisplayMemberPath="Name">
  <ComboBox.ItemsSource>
    <CompositeCollection>
      <CollectionContainer Collection="{Binding Source={StaticResource TheItems}}" />
      <ComboBoxItem Content="" />
    </CompositeCollection>
  </ComboBox.ItemsSource>
</ComboBox>

C'est simple et efficace mais attention tout de même à ne pas en abuser, afin de conserver un code un tant soit peu correctement organisé.

Auteur : Thomas Lebrun

Site : http://blogs.codes-sources.com/tom/

 

Localiser un composant en C#

Imaginons la fenêtre XAML suivante :

<Windowx:Class="Exemple1" 
 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
 xmlns:local="clr-namespace:Exemple1"
 Title="Exemple1" Height="Auto" Width="Auto">
  <StackPanel>
<ListView x:Name="Liste">
<ListViewItem Content="Test 01" />
<ListViewItem Content="Test 02" />
<ListViewItem Content="Test 03" />
</ListView>
</StackPanel>
</Window>

Comment faire pour récupérer la position de Liste en C# ?

Dans notre code nous allons faire appel au composant primaire Canvas :

Double posX = Canvas.GetLeft(this.Liste) ;
Double posY = Canvas.GetTop(this.Liste) ;

Le tour est joué.

Bien évidement les fonctions setLeft et setTop permettront de repositionner le composant.

Auteur : UNi

Blog : http://blog.developpez.com/index.php?blog=167

 

Scroll + Drag&Drop avec une listbox

Voici une petite astuce pour pouvoir dans une même listbox utiliser la barre de scroll avec la souris et utiliser le drag&drop (je vous renvoi à l'excellent article de Thomas Lebrun pour la mise en place du drag&drop http://blogs.developpeur.org/tom/archive/2006/06/08/21434.aspx)

Le principe est simple

J'ai ma listbox dans laquelle j'ai implémenté le drag&drop

<ListBox MouseMove="MouseMoveMethode" AllowDrop="True" 
 SelectionMode="Extended" Width="440" Height="250" 
 x:Name="LBIVueFile" ItemsSource="{Binding}" 
 Background="#FFA9C8FF" />

Si je souhaite utiliser la barre de scroll avec la souris il va croire que je suis en train d'effectuer un drag&drop ce qui n'est pas du tout le cas. Pour éviter d'avoir ce problème il suffit d'entourer la listbox avec un scrollviewer, ce qui nous donne ceci :

<ScrollViewer CanContentScroll="True" Width="440" Height="230" 
 VerticalScrollBarVisibility="Auto"> 
  <ListBox MouseMove="MouseMoveMethode" AllowDrop="False" 
   SelectionMode="Extended" Width="440" x:Name="LBIVueFile" 
   ItemsSource="{Binding}" Background="#FFA9C8FF" /> 
</ScrollViewer>

Auteur : UNi

Site : http://blog.developpez.com/index.php?blog=167

 

Animation

Storyboard :

Il arrive parfois que l’on veuille faire référence à une propriété d’un enfant d’une Window, d’une Page ou d’un UserControl dans un Storyboard situé dans les ressources de celui-ci.
Pour y arriver, il suffit de préciser l’attribut Storyboard.TargetName avec le nom x:Name de l’enfant et ensuite de préciser sa propriété comme on le ferait normalement dans l’attribut Storyboard.targetProperty d’une balise AnimationUsingKeyFrames :

<ObjectAnimationUsingKeyFrames BeginTime="00:00:00" 
 Storyboard.TargetName="border" Storyboard.TargetProperty="Background">

En ayant bien sûr précisé le x:Name de la Border :

<Border x:Name="border">

Et pour appeler un Storyboard défini dans un fichier XAML à partir du code, il suffit d’utiliser la méthode beginStoryboard avec le nom du Storyboard :

this.BeginStoryboard((Storyboard)this.FindResource("myStoryboard"));

Au final, rien de bien compliqué en soit, mais que l'on peut chercher durant un moment si on ne le sait pas.

Auteur : Jérémie Bertrand

Site : http://blog.developpez.com/laedit/

 

Interface graphique

Comment faire pour masquer un contrôle, plutôt que de le désactiver, si la commande qui lui est liée est désactivée ?

Pour cela, on va commencer par déclarer un petit converter, BooleanToVisibilityConverter. Attention, pas besoin de le redéfinir soi-même: celui-ci est disponible de base dans WPF.

<BooleanToVisibilityConverter x:Key="convVisibility" />

Ensuite, il ne reste plus qu’à faire un peu de binding sur la propriété Visibility du contrôle, par rapport à SA propriété IsEnabled:

<Button Content="Supprimer" Command="ApplicationCommands.Delete"
Visibility="{Binding IsEnabled, RelativeSource={x:Static RelativeSource.Self}, Converter={StaticResource convVisibility}}"/>

Simple mais terriblement efficace !

Auteur : Thomas Lebrun

Site : http://blogs.codes-sources.com/tom/

 

 

 

Afficher toutes les couleurs disponible avec WPF

Pour cela c’est très simple. On va d’abord déclarer une méthode qui va nous servir à récupérer les couleurs :

public PropertyInfo[] GetColors(Type type) 
{ 
  return type.GetProperties(); 
} 


Et ensuite, on l’utilise en tant que ObjectDataProvider et on affiche les couleurs dans une combobox :

<Window.Resources>
  <ObjectDataProvider x:Key="colors" MethodName="GetColors" ObjectType="{x:Type local:Tools}">
    <ObjectDataProvider.MethodParameters>
<x:Type TypeName="Colors"/>
</ObjectDataProvider.MethodParameters>
</ObjectDataProvider>
<DataTemplate x:Key="dTemplate">
<StackPanel Orientation="Horizontal">
<Rectangle Width="16" Height="12" Fill="{Binding Name}" Stroke="#FF000000"/>
<TextBlock Margin="1" Text ="{Binding Name}" Foreground="{Binding Name}" />
</StackPanel>
</DataTemplate>
</Window.Resources>
<Grid>
<ComboBox ItemsSource="{Binding Mode=OneWay, Source={StaticResource colors}}" 
   ItemTemplate="{DynamicResource dTemplate}" Margin="50,50,50,0" VerticalAlignment="Top" />
</Grid>

N'oubliez pas de mettre le bon namespace.

Auteur : Nicolas Biedermann

Blog : http://blogs.developpeur.org/bidou/

Site : http://www.nicolasbiedermann.ch

 

Afficher toutes les fonts disponibles avec leurs représentations

Il vous suffit de placer ce code XAML dans votre fenêtre :

<Grid>
   <ComboBox Width="120" Height="25" x:Name="FontSelector" ItemsSource="{x:Static Fonts.SystemFontFamilies}">
      <ComboBox.ItemTemplate>
         <DataTemplate>
            <TextBlock Text="{Binding}" FontFamily="{Binding}"/>
         </DataTemplate>
      </ComboBox.ItemTemplate>
   </ComboBox>
</Grid

 

Auteur : Nicolas Biedermann

Blog : http://blogs.developpeur.org/bidou/

Site : http://www.nicolasbiedermann.ch

 

 

Utilisez le ribbon dans vos applications WPF

Vous avez déjà surement remarqué le ruban dans les applications office :

clip_image002

Mais comment faire pour intégrer rapidement le même composant dans vos applications wpf ?

Microsoft vient de mettre à disposition une librairie à télécharger ici.

Comment l’utiliser ? Tout d’abord insérer le projet téléchargé ci-dessus et ajouter une référence à votre projet initial.

Ensuite il suffit d’utiliser la librairie:

  • Déclaration de l’espace de nom
xmlns:c="clr-namespace:Microsoft.Windows.Controls.Ribbon;assembly=RibbonControlsLibrary"

  • Charger l’un des nombreux thèmes graphiques présents dans la librairie:
<Window.Resources> 
  <ResourceDictionary> 
    <ResourceDictionary.MergedDictionaries> 
      <ResourceDictionary x:Name="rdTheme" Source="/RibbonControlsLibrary;component/Themes/Office2007Silver.xaml" /> 
    </ResourceDictionary.MergedDictionaries> 
  </ResourceDictionary> 
</Window.Resources>

  • Puis utilisez les composants, par exemple:
<c:Ribbon x:Name="mainRibbon" />

Auteur : Julien Dollon

Site : http://blogs.dotnet-france.com/juliend

 

 

Créer un effet de transparence en WPF

A l’occasion de la création d’un simple menu, j’ai souhaité avoir un effet de transparence sur mes boutons:

clip_image003

Nous allons voir comment réaliser l’effet de transparence.

Tout d’abord voici à quoi ressemble le template, très basique, des boutons ci-dessus:

<StackPanel OpacityMask="{x:Null}" Cursor="Hand" 
 x:Name="stackPanel" RenderTransformOrigin="0.5,0.5">
<Grid x:Name="MaGrid" Height="50" Width="Auto">
<ContentPresenter />
</Grid>
</StackPanel>

Je vais ensuite rajouter un rectangle en dessous de ma grid, y insérer un virtualbrush qui copiera le contenu de ma grid. Puis j’appliquerai une transformation à mon rectangle afin de le retourner et lui donner un effet de transparence.

Voici le code à ajouter entre </Grid> et </StackPanel>

<Rectangle Height="50" RenderTransformOrigin="0.5,0.5">
  <Rectangle.OpacityMask>
<LinearGradientBrush SpreadMethod="Reflect" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#00000000" Offset="0"/>
<GradientStop Color="#B3FFFFFF" Offset="1"/>
</LinearGradientBrush>
</Rectangle.OpacityMask>
<Rectangle.RenderTransform>
<TransformGroup>
<ScaleTransform ScaleY="-1"/>
</TransformGroup>
</Rectangle.RenderTransform>
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=MaGrid}" Stretch="Uniform"/>
</Rectangle.Fill>
</Rectangle>

Bon rien de bien compliqué mais toujours bon de revoir ses classiques.

Auteur : Julien Dollon

Site : http://blogs.dotnet-france.com/juliend

 

Changer le curseur de vos applications

Il suffit de créer un Canvas contenant votre nouveau curseur (une image par exemple) intégré au canvas principal.

Mettre l’utilisation du curseur par défaut à None:

<UserControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="Cursor.Page" Width="640" Height="480">
<Canvas x:Name="LayoutRoot" Background="#FFFFFFFF"
MouseEnter="LayoutRoot_MouseEnter" 
   MouseMove="LayoutRoot_MouseMove" Cursor="None">
<Canvas Height="20" Width="20" x:Name="NewCursor" Visibility="Visible"
     Canvas.Left="310" Canvas.Top="230">
<Image Height="Auto" Width="20" Source="newcursor.png" Stretch="Fill"
HorizontalAlignment="Center" VerticalAlignment="Center"/>
</Canvas>
</Canvas>
</UserControl>

Et s’abonner aux événements MouseEnter, MouseLeave:

private void LayoutRoot_MouseEnter(object sender, MouseEventArgs e)
{ 
PointMousePoint=e.GetPosition(this);
Canvas.SetLeft(NewCursor,MousePoint.X);
Canvas.SetTop(NewCursor,MousePoint.Y);
} 
private void LayoutRoot_MouseMove(object sender, MouseEventArgs e)
{ 
PointMousePoint=e.GetPosition(this);
Canvas.SetLeft(NewCursor,MousePoint.X);
Canvas.SetTop(NewCursor,MousePoint.Y);
}

private void LayoutRoot_MouseEnter(object sender, MouseEventArgs e) 
{ 
Point MousePoint = e.GetPosition(this); 
Canvas.SetLeft(NewCursor, MousePoint.X); 
Canvas.SetTop(NewCursor, MousePoint.Y); 
} 

clip_image004

Auteur : julien Dollon

Site : http://blogs.dotnet-france.com/juliend

 

Astuces sur les ListBoxItems

Par défaut, lorsque vous allez vous positionner sur un des ListBoxItem, sa couleur de fond passera en bleu de la même façon que si votre application perd le focus, les ListBoxItem sélectionnés auront un font gris pâle :

clip_image005clip_image006

Pour éviter ce genre de comportement, vous allez devoir redéfinir deux Brush système qui sont utilisé automatiquement lorsque le ListBoxItem est sélectionné. Vous pouvez faire cette manipulation dans les ressources du style de vos ListBoxItem :

<Style.Resources>
  <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent"/>
  <SolidColorBrush x:Key="{x:Static SystemColors.ControlsBrushKey}" Color="Transparent"/>
</Style.Resources>

La couleur HighlightBrushKey est le bleu affiché lorsque l’item est sélectionné (ici passé à transparent) et ControlBrushKey est le gris pâle de l’image de droite si dessus (ici passé à transparent également). Dès lors, deuxième problème résolu !

Un autre problème qui survient lorsque vous naviguez dans vos ListBoxItem à l’aide du clavier, ceux-ci s’entourent d’une bordure noire en pointillés. Pour éviter l’apparition de celle-ci, il vous suffit tout simplement de modifier le style FocusVisualStyle de votre ListBoxItem ou de le mettre à null :

<ListBoxItem FocusVisualStyle="Null" />

Bien sûr, ces astuces peuvent être utilisées avec n’importe quel contrôle.

Auteur : Julien Corioland

Site : http://blogs.dotnet-france.com/julienc

 

Outils et composants

Word 2007 XAML Generator : permet de générer du XAML à partir de document Word. Très pratique pour inclure de longs textes dans une application.
Site : http://www.codeplex.com/Word2007ToXaml
Gratuit

FluidKit : c'est une bibliothèque de composants WPF assez variés, en passant d'une GlassWindow à un DragDropManager ou un ElementFlow (comme iTunes pour présenter les albums).
Site : http://www.codeplex.com/fluidkit/
Gratuit

XAML Templates : c'est un site qui propose à la vente des templates XAML, afin que les développeurs ne s'embêtent plus avec le design de leur application.
Il y a un sample gratuit qui est d'assez bonne qualité.
Site : http://www.xamltemplates.net/
Payant

IPod Controls : c’est une librairie de contrôle de style "IPod".
Site : http://www.codeplex.com/WpfIpodControls
Gratuit

BookControls : il permet de simuler un livre, en WPF et en silverlight. On peut mettre n'importe quel composant sur ses pages, il les gère.
Site : http://www.codeplex.com/wpfbookcontrol
Gratuit

Pixels Shaders Effect : Librairie d'effets sur des images (entres autres Magnify, Monochrome, Pixelate, Ripple, Swirl, Tone, Toon, and ZoomBlur ) et d'effets de transitions.
Site : http://wpffx.codeplex.com/
Gratuit

WPF Transition Framework (WTF) : une librairie de transition en cours de développement, seulement 4 transitions sont disponibles pour le moment (BlurIn/BlurOut et FadeIn/FadeOut). Mais elle propose le choix de la qualité de l'animation.
Site : http://wtf.nukeation.com/
Gratuit

XCeed Datagrid : XCeed propose une datagrid en version 'express' (gratuit).
Site : http://xceed.com/Grid_WPF_Intro.html
Gratuit

BlackLight : une librairie de contrôles WPF/Silverlight très bien fournis.
Site : http://www.codeplex.com/blacklight
Gratuit

Mole : c'est un visualiseur du debugger qui permet de parcourir le Visual Tree d'une fenêtre ou page WPF. On peut voir toutes les valeurs des propriétés, et même l'origine de la valeur (par défaut, style, binding...), changer les valeurs, voir un aperçu visuel de chaque contrôle.Très pratique pour déboguer des templates.
Site : http://karlshifflett.wordpress.com/mole-for-visual-studio/
Gratuit

AvalonDock : c’est un système de layout permettant d'avoir des onglets "déplaçables", des fenêtres flottantes et des panneaux ancrables/masquables automatiquement.
Site : http://avalondock.codeplex.com/
Gratuit

Visifire : c’est une librairie de contrôles open source WPF/Silverlight de visualisation de données. Elle propose toutes sortes de graphiques, animés ou non.
Site : http://www.visifire.com/
Gratuit

Odyssey : c’est une librairie de contrôles WPF proposant entre autres une OutlookBar, une BreadCrumBar (comme l’explorer de vista), une ExplorerBar ou encore un Ribbon.
Site : http://odyssey.codeplex.com/
Gratuit

 

Et pour ceux qui manqueraient encore de réponses, voici une excellente FAQ sur WPF et Silverlight sur le site CodeProject :

http://www.codeproject.com/KB/WPF/WPFSilverLight.aspx

C#, WPF , , , , , ,