Archive for the 'Silverlight' Category


Protéger une application Windows Phone 7 sur la MarketPlace

Aucun commentaire

Vous l'avez sans doute remarqué si vous avez un Windows Phone 7, la Market place windows Phone c'est juste la jungle. Vous trouverez souvent ce que vous recherchez et sans doute beaucoup plus. C'est ce dernier point qui me pose le plus de problème : vous trouverez très souvent plusieurs applications avec le même nom (sans parler des musiques), des logos très légèrement modifiés et des fonctionnalités similaires. Sans même parler de piratage car cela n'est pas possible, n'importe quel développeur ou entreprise peut à loisir créer une application avec des fonctionnalités identiques lorsque celles-ci ne sont pas complexes à développer. Vous trouverez donc souvent 3 / 4 (et quelques fois plus) applications portant le même nom.

Ce problème est, il me semble, complètement propre à Windows phone 7 car en tant qu'utilisateur, je n’ai pas remarqué ce phénomène sur l'AppStore.

Pour résumer même si l’application est sortie un mois , deux mois ou 1 an avant et fut la première portant ce nom, rien n’empêche un développeur ou une entreprise de déposer la même application par la suite avec un logo similaire et un nom exactement identique. La réponse de Microsoft est : il est nécessaire de porter plainte en justice pour protéger le nom de l'application et l'idée de logo. Imaginez donc que vous deviez porter dix plaintes pour 10 applications différentes. Dès lors en tant que développeur Windows Phone 7 et Silverlight, je me pose les questions suivantes :

1 - Je trouve une bonne idée avec un nom idéal et je suis une petite structure, comment faire pour protéger mon application ?

2 - Comment faire pour que mon application soit rapidement trouvée sur la market place ?

3 - Qu’est-ce qui différencie mon application des autres et qu'est-ce qui la protège ?

A titre personnel, je pense qu'une petite structure a très peu de moyens pour se défendre mis à part une action légale. Sur la Market place votre application et son nom surtout pourrait être déposées avec les mêmes fonctionnalités, seul recours la loi. Mais quelle loi, il me semble que cet aspect là est très délicat car il faudra sans doute déposer un brevet internationale et/ou passer par tous les outils possibles à votre disposition.

Pour que votre applications soit rapidement trouvée, pas de mystère, il faut quelle soit utilisée et bien notée par les WindowsPhonaute (ou Marketplacenaute), ou que vous possédiez d'autres moyens marketing comme un site, une campagne de pub, ou une application hors windows phone qui y soit reliée. Cette question renvoie à la question trois.

Ce qui va différencier votre applications des autres ayant le même nom :

  • Les ScreenShots avec des contenus graphiques uniques. Ce contenu est beaucoup plus difficile à copier contrairement au nom. Une banque d'image unique de par son contenu par exemple.
  • Les fonctionnalités complexes, qui ne sont pas à la portée de tous.
  • Une expérience utilisateur sans aucune faille.

Tous ces éléments seront autant de protection contre la recopie de votre application. Mais alors qu'est-ce qu'il y a de changer avec l'AppStore ? Je dirai un aspect romantique, l'aspect Christophe Colomb :) . On a tous eu l'idée de créer un jour l'application avec THE IDEE(IDEA :) . Sauf qu'aujourd'hui, le développeur qui dans son coin souhaite créer cette application même avec l'idée du siècle, ne pourra pas assurer la protection de son application faute de moyens financiers. Car le nom qu'il dépose peut, du jour au lendemain être complètement piraté. De longs mois de procédures juridique sont à la clef de tous recours. Cela peut couter très cher...

Aucune réponse technique à ce problème n'est la bonne, aucune réponse légale n'est bonne non plus à moins que vous fassiez partie d'une moyenne / grande entreprise et que vous disposiez de beaucoup, beaucoup de temps devant vous. La bonne réponse est multiple c'est la réponse artistique, la réponse de l'unique, la réponse du contenu et d'un développement parfait, d'une ergonomie parfaite. Cela sera beaucoup plus dur à copier. Donc à ceux qui postent des applications juste pour en poster alors que d'autres du même type existent, s'il vous plait arrêtez, vous ne gagnerez pas d'argent de cette manière. Cela nuit à la MarketPlace et au fantastique outil qu'est Windows Phone 7.

Dark & Light Themes avec Windows Phone 7

Aucun commentaire

    Depuis le service pack, Blend s'est enrichi de nombreuses fonctionnalités dont l'une permet de créer des applications Windows Phone 7. L'un des grands avantages de Blend est son extensibilité, les développeurs de MS ont naturellement ajouté un onglet qui facilite la prévisualisation d'une application WP7 dans sa version finale. Vous pouvez changer l'orientation de l'application, modifier le thème de couleur, tester l'application avec l'émulateur (ou un device) ou encore choisir le thème lumineux, Dark ou Light.

    Ces options sont très utiles, elles vous permettent de tester vos styles, modèles et composants personnalisables dans diverses configurations. C'est notamment le cas avec les deux thèmes lumineux. Contrairement au changement d'orientation du téléphone, vous ne pouvez pas réellement être notifié des changements de thèmes à l'exécution. Toutefois, il suffit d'utiliser les noms des ressources existantes pour préserver cette fonctionnalité lors du développement de vos composants. C'est notamment le cas pour le LayoutGridSelector que je développe actuellement comme vous pouvez le constater ci-dessous.

    La liste des ressources graphiques utilisées par WP7 est ici. Il est intéressant de noter plusieurs petits détails. Il est possible d'écraser une partie ou la totalité du thème chargé. Il vous suffit pour cela de créer une ou plusieurs ressources de couleur ou brush possédant le même nom que celles nativement chargées. Vous pouvez faire le test en changeant la couleur de sélection, créez une ressource de couleur (vert par exemple) comme montré ci-dessous puis placez un Slider dans la grille principale pouvoir la couleur de sélection changée :)

    Il existe également quatre ressources particulières, nommées PhoneDarkThemeVisibility, PhoneLightThemeVisibility, PhoneDarkThemeOpacity, PhoneLightThemeOpacity qui peuvent s'avérer super utiles. Elles permettent aisément d'afficher ou de cacher un objet selon que l'on soit dans le mode d'affichage lumineux ou sombre.

    Microsoft Keynote lateshow by SteveB @ CES

    Aucun commentaire

      Steve Balmer a tenu la Keynote de Microsoft au CES de Las Vegas cette nuit à 4h30 (heure française). Cette heure fut relativement intense en informations.

      Voici une résumé succinct de la Keynote :

      Nouvelle XBox et Kinect

      • Kinect fonctionne avec zune for XBox et NetFlix, HuluPLUS, tous les jeux ESP
      • Déplacer la time line, choisir une musique un film ou n'importe quel autre média est désormais possible via Kinect
      • Gestion totale des expressions faciales
      • Avatar Kinect vous permet de participer à une conférence multi-utilisateurs, il vous faudra un compte premium à cette fin
      • 30 millions de XBox live account
      • 1ère console vendue aux états unis
      • 50 millions dans le monde sont déployés
      • 8 million Kinect vendus

      Windows Phone 7

      • le jeux Fable - Coin Golf sur WP7
      • 5500 applications actuellement proposées sur WP7
      • 20000 développeurs
      • Microsoft investira lourdement dans le projet dans les prochaines années
      • Copier-Coller supporté dans la prochaine mise à jour

      Windows 7 et Multitouch

      • supporte pleinement les périphériques multitouch comme promis
      • 10 contacts à la fois sur l'une des démos pour activer un clavier tactile

      Surface 2

      • D'une épaisseur de 4 pouces
      • Embarque une technologie complètement différente avec couche de projection d'informations additionnelles
      • Résolution améliorée
      • Consommation d'énergie moindre
      • le prix de la table devrait être en forte baisse, ce qui permettra de la démocratiser
      • API améliorée
      • A base de caméras infrarouge
      • Position verticale désormais possible

      TooltipHelper [Custom Control]

      Aucun commentaire

        L'une des problématiques que l'on rencontre lorsque l'on travaille avec Silverlight, c'est la difficulté de modifier le style de certains contrôles. L'un des exemples les plus flagrants est la customisation du contrôle ToolTip. De plus dans environnement Silverlight, les ToolTip possèdent moins de capacités que sous WPF. Il est par exemple impossible de définir un délai pour l'apparition et la disparition du ToolTip. Je mets donc en téléchargement un contrôle dont le but est de simplifier la mise en oeuvre d'un ToolTip simple à configurer. Ce contrôle a pour but d'accompagner des zones de saisie, de sélection ou tout autre contrôle afin de signifier à l'utilisateur leur mode de fonctionnement.

        Il est possible de :

        - Modifier le style et le template du ToolTip directement dans Blend ou d'en créer une copie.

        - d'écouter les événements Opened et Closed

        - de définir un en-tête, une corps et un pied

        - de définir un délai d'apparition / disparition

        - de définir le mode de placement

        La dll est téléchargeable Ici.

        LayoutGridSelector WP7 [Custom Control]

        Aucun commentaire

          Dans un projet Windows Phone 7 récent, nous avons eu besoin de simplifier l'une des interface utilisateur. Cette dernière permet à un utilisateur de déterminer le nombre de ligne et de colonnes qu'un diaporama peut afficher sur une surface de la dimension d'un Windows Phone (à savoir 800*480). Au départ deux TextBox étaient placés dans une grille et possédaient tous deux une liaison de donnée à deux voies vers des propriété d'un Vue-Modèle. Ce mécanisme n'étant pas des plus simple notamment sur téléphone mobile : click sur TextBox, effacement de l'ancienne saisie et saisie d'un nouveau chiffre et sauvegarde pour finir, j'ai simplifié au maximum cette interface graphique en créant un contrôle qui fait permet à l'utilisateur de définir directement un agencement de manière intuitive.

          Le contrôle peut définir :

          1. Un nombre maximum de colonnes et de lignes sélectionnables (bindable)
          2. La cellule ou la ligne ou la colonne sélectionnée (bindable)
          3. Diffuse un événement lors de la sélection
          4. Utilise en interne des ToggleButton doint vous pourrez modifier le style à loisir via le menu Edit Additionnal Style / Template
          5. De plus, celui-ci fonctionne également pour une application Silverlight classique
          6. J'ai pris en compte toutes les interactions utilisateurs possible du point de vue tactile pour éviter les erreurs de sélection ou d'affichage

          La dll contenant le controle est téléchargeable ici et vous pouvez voir le résultat ci-dessous :

          Install Microsoft Silverlight

          Silverlight 5 Preview Features

          1 commentaire

            Silverlight 5 sera là pour le second semestre 2011, c'est en substance le message que Scott Guthrie a diffusé le 2 décembre lors de l'événement FireStarter. Vous pouvez retrouver la Keynote ici.

            En attendant la version finale, une première version sera disponible courant du premier trimestre 2011. Le salon du MIX se tiendra du 12 au 14 avril 2011 à Las Vegas, il est très probable que la version Bêta sera disponible dès cette date si n'est plus tôt. Scott a tout de même pris le temps de communiquer quelques infos à propos de cette version. Le passage de la version 4 à 5 pourrait être comparée à celui qu'il y a eu entre la version 1 et 2. L'un des indices qui nous mène à cette réflexion concerne la durée des développement qui vont au moins s'étaler sur un an complet (d'après Scott puis qu'elle est prévue sur le second semestre) alors que le passage de la 3 vers la 4 n'avait duré que 10 mois environ. Scott Guthrie rassure tous les acteurs et la communauté Silverlight avec une énorme liste de fonctionnalité. Quelques sujets sont encore vaguement présenté mais on peut facilement imaginer leur impact et leur implémentation. En voici quelques unes de taille :

            -Nouvelle API 3D et moteur 3D

            -Impression vectorielle avec API riche

            -Un système de liaison largement amélioré avec notamment :

            • les customs markup extensions
            • la possibilité de placer des breaks points dans le XAML
            • Ancestor RelativeSource

            -Grosses améliorations à prévoir en termes de mise en page et d'affichage du texte.

            -Accélération GPU bien mieux supportée et intégrée

            -Le décodage hardware des vidéos HD H264, cela signifie que le GPU pourra prendre en charge lui même la décompression vidéo et soulagé le CPU.

            -La possibilité de créer des liaisons de données dans les Setter des styles. Cette fonctionnalité là est réellement très pratique lorsque l'on utilise des propriétés attachées notamment.

            -Les modèles de données (DataTemplate) peuvent désormais être implicite ça s'est plutôt une bonne nouvelle et encore une fois on sent bien que Microsoft essaie au maximum de rapprocher le flux de production Silverlight et WPF.

            -Les tests unitaires pour les IHM seront dorénavant supportés et Microsoft fournira un outil à cet fin :)

            Il y a encore pas mal d'autres fonctionnalités et certaines d'entre elles apparaîtront peut-être au fil du temps et des annonces alors rester à l'écoute car Microsoft investit massivement dans Silverlight 5 et vient de nous le prouver.

            Design time Custom Attributes

            Aucun commentaire

              Il arrive souvent lorsque vous concevez des composants d'avoir besoin d'une représentation au design time, dans Blend, très spécifique. Sans aller jusqu'à développer des design time dlls, les attributs existants peuvent être d'une grande aide (vous pourrez trouver des explications concernant les designs dll par Justin Angel ici). Du coup, je liste ci-dessous une suite d'attributs que j'utilise couramment lors de mes projets, ceux-ci sont accessibles via les espaces de nom System.ComponentModel et System.Windows.Interactivity :

              1. Définir une description au survol d'une propriété ou d'un contrôle dans le panneau Properties
                [Description("ma description")]
              2. Définir une valeur par défaut au Design Time
                [DefaultValue()]
              3. Définir dans quel sous catégorie du panneau propriété la propriété se trouve
                [Category("Common Properties")]
              4. Définir la propriété dans les options avancées d'une sous catégorie ou ne pas l'afficher. C'est cette sous-partie que vous pouvez déplier.
                [EditorBrowsable(EditorBrowsableState.Advanced)]
              5. Définir si une propriété supporte la liaison de donnée et si oui dans quelles directions.
                [Bindable(BindableSupport.Yes,BindingDirection.TwoWay)]
              6. Définir un type de présentation spécifique. Très utile lorsque la propriété est affectée de certain type d'objets, par exemple cibler un état visuel.
                [CustomPropertyValueEditorAttribute(CustomPropertyValueEditor.StateName)]
              7. Lorsqu'une classe définit des objets customizables, faciliter l'accès aux templates via les menus d'accès aux styles additionnels.
                [StyleTypedProperty(Property = "ToolTipStyle", StyleTargetType = typeof(ToolTip))]
              8. Définir une partie de contrôle
                [TemplatePart(Name="maPartieLogique", Type=typeof(FrameworkElement))]
              9. Définir un état visuel
                [TemplateVisualState(GroupName = "CommonStates", Name = "Normal")]
              10. Définir une propriété comme propriété de type Content alternative, celui-ci est réellement très pratique, C'est ce qu'utilise en interne les controles de type TabItem ou les charts de Silverlight ToolKit.
                [AlternateContentProperty()]

              DonutLoader [Custom Control]

              Aucun commentaire


                Pour les besoins d'une production, nous avons eu besoin d'un visuel d'attente (Torus ou Donut Loader) très proche de ce qui se fait déjà déjà sous Windows. Pour cela, j'ai étendu Control puis j'ai ajouté quelques Dependency properties :

                #region Dps
                 
                /// 
                /// Set the speed of animation based on
                /// 
                [Category("Common Properties")]
                [Description("Allow to define animation's duration")]
                public TimeSpan Duration
                {
                    get { return (TimeSpan)GetValue(DurationProperty); }
                    set { SetValue(DurationProperty, value); }
                }
                 
                // Using a DependencyProperty as the backing store for SpeedRatio.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty DurationProperty =
                    DependencyProperty.Register("Duration", typeof(TimeSpan), typeof(DonutLoader), new PropertyMetadata(TimeSpan.FromSeconds(1), new PropertyChangedCallback(OnDurationChanged)));
                 
                private static void OnDurationChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
                {
                    var donutLoader = d as DonutLoader;
                 
                    if (d != null)
                    {
                        ClockState cs = donutLoader.boucle.GetCurrentState()
                 
                        donutLoader.boucle.Stop();
                 
                        donutLoader.daBoucle.Duration = (TimeSpan)e.NewValue;
                 
                        if (cs == ClockState.Active)
                        {
                            donutLoader.boucle.Begin();
                        }
                    }
                }
                 
                /// 
                /// Percent of progression
                /// 
                [Category("Common Properties")]
                [Description("Current progression value")]
                public double Percent
                {
                    get { return (double)GetValue(PercentProperty); }
                    set { SetValue(PercentProperty, value); }
                }
                 
                // Using a DependencyProperty as the backing store for Percent.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty PercentProperty =
                    DependencyProperty.Register("Percent", typeof(double), typeof(DonutLoader), new PropertyMetadata(0d));
                 
                /// 
                /// Allow to  hide percent textBlock
                /// 
                [Category("Common Properties")]
                [Description("Show/Hide progression value")]
                public Visibility PercentVisibility
                {
                    get { return (Visibility)GetValue(PercentVisibilityProperty); }
                    set { SetValue(PercentVisibilityProperty, value); }
                }
                 
                // Using a DependencyProperty as the backing store for PercentVisibility.  This enables animation, styling, binding, etc...
                public static readonly DependencyProperty PercentVisibilityProperty =
                    DependencyProperty.Register("PercentVisibility", typeof(Visibility), typeof(DonutLoader), new PropertyMetadata(Visibility.Visible));
                 
                #endregion

                A ce stade, tout fonctionne comme prévu, mais un petit bug m'a pris un peu de temps à résoudre dans les lignes suivantes.

                private void SetOpacityMask()
                {
                BitmapImage bi = new BitmapImage() { UriSource = new Uri("/Tweened.Controls;component/bitmaps/ProgressBitmap.png", UriKind.RelativeOrAbsolute) };
                 
                     ImageBrush ib = new ImageBrush();
                 
                     ib.ImageSource = bi;
                 
                     _DonutFrameworkElement.RenderTransform = new CompositeTransform() { CenterX = .5, CenterY = .5 };
                 
                     _DonutFrameworkElement.OpacityMask = ib;
                }
                 
                private void SetStoryboard()
                {
                     boucle.Children.Add(daBoucle);
                 
                     Storyboard.SetTargetProperty(daBoucle, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.Rotation)"));
                 
                     daBoucle.From = 0;
                 
                     daBoucle.To = -360;
                 
                     daBoucle.RepeatBehavior = RepeatBehavior.Forever;
                 
                     daBoucle.Duration = Duration;
                }

                Lorsque l'on joue l'animation de rotation par C# ou XAML, l'objet qui subit l'animation disparaît soudainement au runtime. Après avoir passé un peu de temps sur ce bug, j'ai décidé non pas d'animer l'objet lui même mais son remplissage :

                private void SetOpacityMask()
                {
                    BitmapImage bi = new BitmapImage() { UriSource = new Uri("/Tweened.Controls;component/bitmaps/ProgressBitmap.png", UriKind.RelativeOrAbsolute) };
                 
                    ImageBrush ib = new ImageBrush();
                 
                    ib.ImageSource = bi;
                 
                    ib.RelativeTransform = new CompositeTransform() { CenterX = .5, CenterY = .5 };
                 
                    //ancienne version
                    //_DonutFrameworkElement.RenderTransform = new CompositeTransform() { CenterX = .5, CenterY = .5 };
                 
                    _DonutFrameworkElement.OpacityMask = ib;
                }
                 
                private void SetStoryboard()
                {
                    boucle.Children.Add(daBoucle);
                 
                    Storyboard.SetTargetProperty(daBoucle, new PropertyPath("(UIElement.OpacityMask).(Brush.RelativeTransform).(CompositeTransform.Rotation)"));
                 
                    //ancienne version
                    //Storyboard.SetTargetProperty(daBoucle, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.Rotation)"));
                 
                    daBoucle.From = 0;
                 
                    daBoucle.To = -360;
                 
                    daBoucle.RepeatBehavior = RepeatBehavior.Forever;
                 
                    daBoucle.Duration = Duration;
                }

                j'ai donc remplacé la ligne ciblant la propriété à animer :

                Storyboard.SetTargetProperty(daBoucle, new PropertyPath("(UIElement.RenderTransform).(CompositeTransform.Rotation)"));

                par :

                Storyboard.SetTargetProperty(daBoucle, new PropertyPath("(UIElement.OpacityMask).(Brush.RelativeTransform).(CompositeTransform.Rotation)"));

                Là, au miracle, plus aucun bug, tout fonctionne parfaitement. C'est la première fois que j'anime, au sein d'un custom contrôle, un objet avec une image en masque d'opacité et j'ai bien perdu 30 minutes là dessus. Si quelqu'un a une idée du pourquoi de ce bug je suis preneur.

                FireStarter Silverlight

                Aucun commentaire

                  Illuminez vos compétences Silverlight avec la toute nouvelle session globale Firestarter Silverlight !
                  Pour vous raffraichir un peu les idées le Silverlight Firestarter est un événement mondial d'une journée, diffusé en direct et présenté par Scott Guthrie. Vous pourrez à cette occasion directement communiquer avec l'équipe produit Silverlight, vous aurez également accès à des atelier d'auto-formation.

                  Suivez le programme :)

                  Pour vous inscrire c'est ici.

                  TextBox Attached Property

                  Aucun commentaire

                    Lorsque l'on conçoit avec MVVM en Silverlight, on se retrouve rapidement bloqué en matière de binding car le framework Silverlight contrairement à WPF n'a pas pour but d'être exhaustif. De nombreux comportements notamment la mise à jour d'un Binding, peuvent être configurés de manière direct dans WPF au niveau du XAML. Dans Silverlight, la mise à jour d'une liaison de données est souvent réalisée sur l'événement LostFocus ce qui n'est pas l'idéal. En effet lorsque l'utilisateur arrive sur le dernier champ d'un formulaire, juste avant de cliquer sur le bouton, ce dernier ne sait pas forcément si les données qu'il a saisit sont correctes. Pour le savoir celui-ci devra faire en sorte de perdre le focus sur le champ de saisie en question. L'experience utilisateur n'est pas vraiment friendly dans ce cas. Dès lors, on pense à WPF et à la fameuse option UpdateSourceTrigger=PropertyChanged qui résoudrait notre problème en toute simplicité. Grâce aux propriétés attachées, il est possible de reproduire ce comportement au cas par cas. Pour les TextBox, l'idéal serait d'écrire AutoUpdateBinding="True". Voici donc ci-dessous une propriété attachée qui permet de reproduire ce comportement :

                    public static class MesExtensions
                    {
                        public static bool GetAutoUpdateBinding(DependencyObject obj)
                        {
                            return (bool)obj.GetValue(AutoUpdateBindingProperty);
                        }
                     
                        public static void SetAutoUpdateBinding(DependencyObject obj, bool value)
                        {
                            obj.SetValue(AutoUpdateBindingProperty, value);
                        }
                     
                        // Using a DependencyProperty as the backing store for AutoUpdateBinding.  This enables animation, styling, binding, etc...
                        public static readonly DependencyProperty AutoUpdateBindingProperty =
                            DependencyProperty.RegisterAttached("AutoUpdateBinding", typeof(bool), typeof(TextBox),
                            new PropertyMetadata(false, new PropertyChangedCallback(OnAutoUpdateChanged)));
                     
                        private static void OnAutoUpdateChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
                        {
                            TextBox tb = d as TextBox;
                     
                            if (tb == null)
                            {
                                return;
                            }
                            if (System.Convert.ToBoolean(e.NewValue))
                            {
                                tb.TextChanged += new TextChangedEventHandler(tb_TextChanged);
                            }
                            else
                            {
                                tb.TextChanged -= tb_TextChanged;
                            }
                        }
                     
                        static void tb_TextChanged(object sender, TextChangedEventArgs e)
                        {
                            TextBox tb = sender as TextBox;
                            if (tb == null)
                            {
                                return;
                            }
                     
                            BindingExpression be = tb.GetBindingExpression(TextBox.TextProperty);
                     
                            if (be != null)
                            {
                                be.UpdateSource();
                            }
                        }
                    }

                    Ce n'est pas la seule problématique que pose MVVM en matière de binding, le fait de lier des données des collections en lecture seule en est une autre que nous verrons dans un autre post...

                    « Previous PageNext Page »