# Tuesday, May 27, 2008

Silverlight Command pattern et AttachedProperty

Les AttachedProperty

Ce type de propriété permet d'enrichir les propriétés existantes d'un objet. Ce sont des propriétés qui n'ont pas forcément de sens au niveau du contrôle lui-même, mais qui en ont au vu d'un contexte externe. Les AttachedProperty les plus connues sont Canvas.Left, Canvas.Top, Grid.Column et Grid.Row. Vous remarquerez que la propriété colonne n'a aucun sens sur un contrôle en dehors du contexte de la grille.

Ces AttachedProperty nous permettent d'étendre le comportement de nos contrôles. Nikhilk nous donne un exemple d'implémentation d'un framework de comportement sur son blog.

Le Command pattern

Ce pattern a pour but de séparer le comportement de la partie IHM. L'idée est de ne plus s'attacher directement aux événements des contrôles et de passer par un objet Command qui va faire la liaison entre le comportement et la saisie des utilisateurs.
Vous trouverez une bonne description du pattern Command en WPF sur le site de microsoft. Cette séparation permet de pouvoir déclencher l'action depuis l'IHM mais aussi depuis d'autres classes métiers.

Le code

La classe centrale est CommandService. Elle défini les AttachedProperty, c'est elle qui devra être référencée dans le xaml pour relier un contrôle à une commande.

<UserControl  xmlns="http://schemas.microsoft.com/client/2007"

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

   xmlns:sle="clr-namespace:SLExtensions.Input;assembly=SLExtensions"

...

        <Button Content="Open" Width="50" Height="30"

                      sle:CommandService.Command="Open"

                      sle:CommandService.CommandParameter="{Binding OpenFileInfo, Source={StaticResource controller}}" />

 

...

</UserControl>

Dans cet exemple, le bouton "Open" est bindé à la commande Open. On passe en paramètre à la commande un object OpenFileInfo qui est stocké sur le contrôleur de la page. Il sert à passer les paramètres d'exécution de la commande.

Du coté métier, le contrôleur de la page s'attache à l'événement Executed de la commande

...

 TestCommands.OpenCommand.Executed += new ExecutedEventHandler(OpenCommand_Executed);

...

void OpenCommand_Executed(object sender, ExecutedEventArgs e)

{

    OpenFileDialogInfo info = e.Parameter as OpenFileDialogInfo;

    if (info != null)

    {

        using (OpenFileDialog ofd = new OpenFileDialog())

        {

            ofd.EnableMultipleSelection = info.EnableMultipleSelection;

            ofd.Filter = info.Filter;

            ofd.ShowDialog();

        }

    }

}

 

Téléchargements Sources

#    Comments [0] |
# Monday, May 26, 2008

Copy source as html VS 2008

J'ai cherché durant le weekend un moyen satisfaisant de poster du code sur mon blog sans perdre le formatage. J'ai fais plusieurs essais plus ou moins réussis. Mon choix s'est arrêté sur CopySourceAsHtml. Il a bien sur fallu que je trouve une version compatible avec Visual Studio 2008 contenant ce patch corrigeant un problème d'accès au presse-papier. Finalement, je suis reparti des sources. Je publie donc ici les sources modifiées ainsi que les binaires à mettre dans

Voici un exemple de ce que ça peut donner "%userprofile%\Documents\Visual Studio 2008\Addins"

namespace SilverlightApplication5

{

    public partial class Page : UserControl

    {

        public Page()

        {

            InitializeComponent();

        }

    }

}

Téléchargements :

#    Comments [0] |
# Sunday, May 25, 2008

Le data binding en Silverlight

Le data binding est une des fonctionnalités les plus puissantes de Silverlight et WPF. Il n'est plus nécessaire de passer du temps à faire du code pour la synchronisation des données. Cela contribue à la séparation de la partie visuelle de la partie métier.

Fonctionnement

En beta 1, le data binding est implémenté sur tout les objets qui héritent de FrameworkElement. Les propriétés de ce contrôle peuvent être liées à un objet source spécifiée lors du binding ou être liées au contexte de binding en cours. Le binding en cours est stockée par la propriété DataContext.

  • Exemple 1:

    1 <UserControl x:Class="Ucaya.SilverlightTest.Page"

    2    xmlns="http://schemas.microsoft.com/client/2007"

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

    4    xmlns:sys="clr-namespace:System;assembly=mscorlib"

    5    Width="400" Height="300">

    6     <UserControl.Resources>

    7         <sys:String x:Name="src">Binding source</sys:String>

    8     </UserControl.Resources>

    9     <StackPanel x:Name="LayoutRoot" Background="White">   

   10         <TextBlock x:Name="tb1" Text="{Binding Source={StaticResource src}}"/>

   11         <TextBlock x:Name="tb2" Text="{Binding Length, Source={StaticResource src}}"/>

   12     </StackPanel>

   13 </UserControl>

Ici, le TextBlock tb1 a sa propriété Text bindée à l'objet src qui se trouve dans les ressources. N'ayant pas spécifié de chemin dans la binding, c'est l'objet lui même qui est lié.
Le TextBlock tb2 est lié à la propriété Length de la source.

  • Exemple 2:

    1 <UserControl x:Class="Ucaya.SilverlightTest.Page"

    2    xmlns="http://schemas.microsoft.com/client/2007"

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

    4    xmlns:sys="clr-namespace:System;assembly=mscorlib"

    5    Width="400" Height="300">

    6     <UserControl.Resources>

    7         <sys:String x:Name="src">Binding source</sys:String>

    8     </UserControl.Resources>

    9     <Grid x:Name="LayoutRoot" Background="White">

   10         <ListBox x:Name="lb" ItemsSource="{Binding Source={StaticResource src}}">

   11             <ListBox.ItemTemplate>

   12                 <DataTemplate>

   13                     <TextBlock x:Name="tb" Text="{Binding }"/>

   14                 </DataTemplate>

   15             </ListBox.ItemTemplate>

   16         </ListBox>       

   17     </Grid>

   18 </UserControl>

La ListBox est bindée de la même manière que dans l'exemple 1. La string étant énumérable, la ListBox instancie un ItemTemplate par valeur de l'énumération.
Le TextBlock à sa propriété Text bindée au contexte de binding en cours fourni par la ListBox. Comme dans l'exemple 1, n'ayant pas fourni de chemin de binding, c'est directement la source du binding qui est liée.

Modes de binding

La synchronisation des valeurs peut se faire de différente manière.

OneTime

La donnée est recopiée de la source vers le contrôle une seule fois lorsque le binding est créé.

OneWay

La donnée est mise à jour dans le sens source vers contrôle à chaque fois que la valeur de la source change. Pour que le binding soit notifié du changement, l'objet source du binding doit implémenter l'interface INotifyPropertyChanged pour les propriétés et INotifyCollectionChanged pour les collections.

TwoWay

La donnée est mise à jour dans le sens source vers contrôle à chaque fois que la valeur de la source change (sous réserve de l'implémentation de INotifyPropertyChanged ou INotifyCollectionChanged) et dans le sens contrôle vers source quand la valeur du contrôle change.

Conversion des données

Il arrive que les données sources ne puissent être converties directement entre les propriétés d'un contrôle et les valeurs de la source. C'est là qu'interviennent les classes de conversion. Elles permettent par exemple de convertir un string en Uri, un string en ImageSource ou encore de formatter un double en string avec 2 nombres après la virgule. Ces convertisseurs sont des classes qui implémentent l'interface IValueConverter.

  • Exemple

Implémentation d'un convertisseur effectuant un string.Format. Affiche une valeur en pourcentage.

Xaml:

 

<UserControl x:Class="Ucaya.SilverlightTest.Page"

   xmlns="http://schemas.microsoft.com/client/2007"

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

   xmlns:sys="clr-namespace:System;assembly=mscorlib"

   xmlns:sle="clr-namespace:SLExtensions.Data;assembly=SLExtensions"

   Width="400" Height="300">

    <UserControl.Resources>

        <sys:Double x:Key="src">0.333333</sys:Double>

        <sle:StringFormatConverter x:Key="formater"/>

        <sys:String x:Key="formatString">{0:p}</sys:String>

    </UserControl.Resources>

    <StackPanel x:Name="LayoutRoot" Background="White">   

        <TextBlock x:Name="tb1"

                  Text="{Binding Converter={StaticResource formater}, ConverterParameter={StaticResource formatString}, Source={StaticResource src}}"/>

    </StackPanel>

</UserControl>

Convertisseur:

// <copyright file="StringFormatConverter.cs" company="SLExtensions.Controls">

// Distributed under Microsoft Public License (Ms-PL)

// </copyright>

 

namespace SLExtensions.Data

{

    using System;

    using System.Windows;

    using System.Windows.Controls;

    using System.Windows.Documents;

    using System.Windows.Ink;

    using System.Windows.Input;

    using System.Windows.Media;

    using System.Windows.Media.Animation;

    using System.Windows.Shapes;

    using System.Windows.Data;

 

    /// <summary>

    /// Convert data to string objects as it passes through the binding engine.

    /// </summary>

    public class StringFormatConverter : IValueConverter

    {

        /// <summary>

        /// Default string format syntax

        /// </summary>

        private const string DefaultStringFormat = "{0}";

 

        #region IValueConverter Members

 

        /// <summary>

        /// Convert source data to string before passing it to the target for display in the UI.

        /// </summary>

        /// <param name="value">The source data being passed to the target.</param>

        /// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the target dependency property.</param>

        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>

        /// <param name="culture">The culture of the conversion.</param>

        /// <returns>

        /// The value to be passed to the target dependency property.

        /// </returns>

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

        {

            if (targetType != typeof(string))

            {

                throw new ArgumentException(Resource.StringFormatConverterExceptionInvalidTargetType);

            }

 

            if (value == null)

            {

                return string.Empty;

            }

 

            string format = (parameter as string) ?? DefaultStringFormat;

            return string.Format(format, value);

        }

 

        /// <summary>

        /// This convertion is not supported

        /// </summary>

        /// <param name="value">The target data being passed to the source.</param>

        /// <param name="targetType">The <see cref="T:System.Type"/> of data expected by the source object.</param>

        /// <param name="parameter">An optional parameter to be used in the converter logic.</param>

        /// <param name="culture">The culture of the conversion.</param>

        /// <returns>

        /// The value to be passed to the source object.

        /// </returns>

        object IValueConverter.ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)

        {

            throw new NotSupportedException();

        }

 

        #endregion

    }

}

#    Comments [0] |
# Wednesday, April 30, 2008

Une RichTextBox en Silverlight

Michael Sync a publié sur son blog et sur CodePlex un Rich Text Editor en silverlight. Je ne l'ai pas encore testé, mais cela semble très prometteur.

rte

#    Comments [0] |

Conditions d'utilisation du serveur de tuiles VirtualEarth

Dans un billet précédent, j'ai présenté un module permettant d'afficher des cartes VirtualEarth en Silverlight. Ce module requête directement le serveur de tuile chez Microsoft sans utiliser le sdk javascript fourni par MS et du coup ne respecte pas la licence d'utilisation de VirtualEarth. Ce matin, un billet sur le blog virtual earth explique comment légaliser cet accès. Il suffit d'insérer un identifiant reçu par webservice lors de l'appel des tuiles.
Vous trouverez donc bientôt une nouvelle version de mon module tenant compte de cet identifiant.

#    Comments [0] |

iSwish sur Windows Mobile un iPhone killer ?

iSwish est un projet de FlickSoftware visant à porter une partie de l'interface iPhone sur Windows Mobile. Bien que la "carte graphique" de l'iPhone soit largement plus puissante que ce qu'on peut trouver sur les machines tournant sous Windows Mobile, le résultat est très fluide.

Source : http://www.engadget.com/2008/04/30/video-iswish-puts-the-iphone-ui-on-any-windows-mobile-phone/

#    Comments [0] |
# Wednesday, April 23, 2008

Cartographie en silverlight

layerhostJe poste sur le labs un début de contrôle de gestion de calques. Le but de ce contrôle est de pouvoir afficher des calques, zoomer, se déplacer dedans, afficher dynamiquement des données sur les nouvelles zones visibles. Ça ressemble furieusement à de la cartographie tout ça. C'est pourquoi les premiers calques que j'ai développés sont des calques Googlemap et Virtual Earth. Les premiers tests sont visibles ici : http://labs.ucaya.com/layerhost/
Ce contrôle devrait bientôt rejoindre une librairie qui sera téléchargeable sur CodePlex

#    Comments [0] |
# Friday, April 18, 2008

Thierry on the reMIX 08 Paris

Vous ne trouvez pas qu'il se la pète ? ;-) PIC-0053

Bon c'est vrai il peut, il a vraiment fait un super taf !

#    Comments [0] |

Agréée CIR

Depuis le mois d'avril 2008 UCAYA est agréée au Crédit d'Impôts Recherche.

Les travaux que vous nous confiez peuvent être soumis au Crédit d'Impôts Recherche s'ils respectent les règles d'éligibilité.

#    Comments [0] |
# Friday, April 04, 2008

Nouveau Site Web

Ca y est, nous avons enfin pu trouver un peu de temps pour réaliser notre site web :-)

#    Comments [3] |
# Wednesday, April 02, 2008

Ucaya, 1 an déjà

Cela fait 1 an aujourd'hui qu'Ucaya a démarré son activité. Nous voyons se dessiner l'avenir sereinement. Si les débuts ont consisté essentiellement en de la prestation de service, nous commençons à développer nos futurs produits en interne. Je ne vous dis pas pour l'instant ce sur quoi nous travaillons, mais je peux déjà vous dire que ça sera en silverlight. Nous avons réalisé beaucoup de tests et projets en interne et nous croyons fortement dans cette technologie.

Petit bilan de l'année écoulée.

Les projets publics

  • XamlTune Au début d'Ucaya, n'ayant pas encore de licence Microsoft, nous développions avec les outils gratuits disponibles sur le marché. Pour faire du Xaml, nous avions besoin de convertir des fichiers Illustrator et SVG en Xaml. Inkscape nous permettait de retoucher les fichiers au format vectoriel et XamlTune nous les convertissait.
    Ce projet est maintenant hébergé sur CodePlex.
  • NHib.Wizard La partie d'accès aux données de nos projets utilise essentiellement NHibernate. Le coût d'entrée à NHibernate est assez élévé. Apprentissage du fichier de mapping, maintenance du schema de la base de données, maintenance des classes métier.
    Ce petit wizard permet de convertir des diagrammes de classes UML XMI en classes métier, fichier de mapping NHibernate et de générer le script de la base de données. Un bon gain de temps pour nos projets.
    Les sources sont disponibles sur la page produit

D'autres projets existent mais ne sont pas montrable en l'état. Dès que je trouve le temps de les remettre d'aplomb je les publie sur le site.

Comme je vous disais plus haut, nous avons beaucoup travaillé avec des logiciels gratuits. Voici la liste des outils que vous pouvez trouver sur mon poste de développement.

#    Comments [2] |

Identification InfoCard (CardSpace) avec Silverlight2

cardspace Voila la conversion du sample js en Silverlight. L'appel à la fonction GetToken lance l'interface InfoCard et retourne le xml d'identification.

InfoCardSample.zip (19,32 KB)
#    Comments [0] |

Animer du HTML avec Silverlight 2

Silverlight possède un système d'animation très poussé. L'idée de ce sample est d'utiliser les storyboards pour agir sur des éléments du DOM.
Le principe est le même que pour le "game loop" d'un jeu. Tous les x millisecondes, on va agir sur les éléments à animer. On récupère la position et la taille d'un élément silverlight qui va servir de modèle et on les applique à l'élément du DOM.

Le projet :

La classe HtmlAnimation est en charge du "game loop". Elle possède une collection de HtmlAnimationPair. Les HtmlAnimationPair font la liaison entre l'élément silverlight et l'élément du DOM.

Site web de test

HtmlAnimation.zip (13,68 KB)
#    Comments [2] |