Bienvenue à Blogs CodeS-SourceS Identification | Inscription | Aide

Benjamin Roux

Silverlight Expert - Silverlight Fan - MVP Client App Dev

Actualités

  • Mon statut Live Messenger :



    View Benjamin Roux's profile on LinkedIn



    Benjamin Roux's Facebook Profile


    MVP Blog Badge.
[Silverlight] Recherche d’un graphiste pour un jeu

Bonjour à tous,

Je suis à la recherche d’un graphiste Silverlight pour la réalisation d’un jeu de stratégie multi-joueur au tour par tour en Silverlight.

Le jeu en lui même est pratiquement terminé, mais je ne peux pas le publier en l’état. J’ai donc besoin d’un graphiste qui pourra m’aider à faire une jolie charte graphique et rendre le jeu attirant.

En cas de succès du jeu et si des revenus en ressortent, il y aura bien évidemment partage égal !

Je suis ouvert à toute proposition.

Localisation d’une application Silverlight

Je viens (il y a 2 mois) de sortir un article sur la localisation d’une application en Silverlight.

C’est par là que ça se passe : Localisation d’une application Silverlight

Souvenirs de la vie d’Isaac Newton en Silverlight

La Royal Society vient de mettre en ligne un mansucrit de William Stukeley racontant la vie d’Isaac Newton avec notamment un passage sur la fameuse pomme qui a mené à la découverte de la loi universelle de gravitation.

Ce manuscrit est disponible en visualisation, ainsi que d’autres, via un player Silverlight mais également via une version xbap.

[Silverlight] Mon entrée pour le MIX 10K Coding Challenge

Salut à tout le monde,

Un petit post pour vous présenter l’entrée que j’ai soumise au concours MIX 10K Coding Challenge.

http://mix10k.visitmix.com/Uploads/140/Thumbnail.jpg

Pour ceux qui ne connaisse pas ce concours, c’est très simple, vous devez soumettre une application dont le code source fait moins de 10Ko. Les technologies autorisées sont Silverlight, HTML5, Gestalt.

Pour ma part, vous l’aurez deviné, j’ai choisi Silverlight, et mon code source fait 9.5Ko.

Alors si vous trouvez mon application sympa, votez pour moi !

http://mix10k.visitmix.com/Entry/Details/140

Merci !

[Silverlight] Bug avec les projets contenant '.Resources'

Salut à tous et bonne année.

Je vais commencer cette nouvelle année en vous signalant un léger problème dans Silverlight (ou dans les Silverlight tools), problème qui m’a tout de même fait perdre 1h30.

Lorsque vous créez un projet contenant les caractères '.Resources', la package xap résultant de la compilation ne sera pas complet. En effet la dll de votre projet sera manquante et vous vous retrouverez avec seulement le fichier AppManifest.xaml.

Vous pouvez recréer le problème en créant un projet TestSL.Resources par exemple et en ouvrant le fichier xap juste après avoir compilé.

J’ai signalé le bug sur le forum de Silverlight : http://forums.silverlight.net/forums/t/153948.aspx

Assez embêtant quand même.

Les nouveautés de Silverlight 4

Bonjour à tous.

Un petit post pour mon nouvel article consacré aux nouveautés de Silverlight 4.

C’est ici que ça se passe : Les nouveautés de Silverlight 4

Je découperais peût-être l’article pour en faire des posts de blogs.

N’hésitez pas à laisser un commentaire si vous voyez une erreur.

[PDC09] En route pour la PDC

La PDC commence dans quelques jours, quant à moi je m'envole pour Los Angeles dès demain matin pour une arrivée dimanche en fin de matinée heure locale.

N'oubliez pas de repasser sur mon blog sur Developpez.com tout au long de l'évènement pour suivre en direct toutes les nouveautés qui vont être présentées.

Je tiens à remercier Microsoft France ainsi que Developpez.com pour cet évènement.

Merci également à Techtra de me donner l'opportunité d'y participer.

Partenaire Or Microsoft et membre prestige du Excellence Gold Partner Program de Microsoft, Techtra est une entreprise privée qui se démarque par son expertise inégalée dans les domaines de la gestion de documents, de contenus, d’automatisation de processus d’affaires, d’intranets, d’intelligence d’affaires et de développement d’applicatifs avec la plateforme SharePoint de Microsoft. Fort de ses 19 années d’expérience dans ces domaines d’affaires, Techtra offre des services de développement, de consultation d’intégration et de développement applicatifs sur Sharepoint. Ses services, produits et solutions d’affaires sont disponibles à travers le monde via un réseau de partenaires stratégiques. http://www.techtra.ca

[Windows] Windows Seven disponible sur Msdn et Technet

Et voilà c’est parti, vous pouvez télécharger Windows 7 à partir de votre compte Msdn ou Technet. En revanche toujours rien sur Connect.

Encore 2h30 pour ma part :(

Bon téléchargement !!

[Mobiles] Présentation du Meizu MiniOne M8 sous Windows CE 6 !

Article originel (par moi) : http://www.developpez.net/forums/d787015/systemes/autres-systemes/mobiles/mobiles-presentation-meizu-minione-m8/


Bonjour,
Je vais sortir des sentiers battus en présentant ici un téléphone dont la notoriété n'a que peu ou pas dépassée les frontières chinoises, j'ai nommé le Meizu MiniOne M8.

Commencons par les caractérisitques :

  • Ecran : 3.4 pouces avec une résolution de 720*48 / Multitouch
  • Processeur cadencé à 667Mhz
  • Mémoire : 256Mo de ROM
  • Capteurs de proximité, gravité (acceleromètre) et de lumière
  • Dimensions : 108*59*12mm
  • Poids : 118gr avec la batterie
  • Couleurs disponibles : Noir/Blanc
  • Stockage : 8/16Go
  • APN : 3.2 Megapixels avec auto focus, le lecteur de photo supporte quant à lui les formats BMP, PNG, JPG et TIF
  • Formats vidéos : AVI, MP4, 3GP, MOV, ASF, MKV, FLV formats
  • Formats audios : AMR, AAC, APE, FLAC, OGG, MP3, WAV, WMA
  • Communication : GSM, EDGE, GRPS, Wifi
  • Fréquences : GSM (850, 900, 1800, 1900 MHz), GPRS
  • Batterie : 1200mAh, 3.7V jusqu'à 370 minutes en communication, 179 heures avec une carte SIM, 374 sans cartes sim, 7 heures en lecture vidéos et 21.5h en lecture de musiques.
  • Langues : Anglais, Chinois simplifié et français sur les derniers firmware
  • OS : MyMobile basé sur Windows CE 6.0

Au sujet du Wifi et au vue de la legislation à ce sujet en Chine, le M8 possède bien une puce Wifi mais la fonctionnalité n'est pas activé dans le firmware, en revanche un crack est disponible pour l'activer.

Bon après tous ces chiffres parlons on peu de la bête.

Comme dit dans les specs, l'écran est donc multitouch et l'applicatif est très réactif (le tout s'améliore à chaque Firmware). En parlant de ce dernier, la dernière "leaked" version est la numéro 0.9.1.9 qui reste donc une version non finalisée. La version finale est quant à elle prévue pour Aout-Septembre avec une refonte totale de l'interface graphique.

L'OS étant basé sur Windows CE 6.0 bon nombres d'application sont d'ores et déjà compatibles et existantes.
Meizu à par ailleurs livré un SDK afin de maximiser le potentiel de l'appareil (utilisation des capteurs par exemples).
Un portage sur Android n'a pas été exlu par le CEO de Meizu annonçant qu'une équipe travaillait sur cette possibilité.
Pour rappel Windows Mobile 6.5 est basé sur Windows CE 5, alors que le futur Windows Mobile 7 sera basé également sur Windows CE 6.
Au niveau capteur nous avons donc un acceleromètre devenu assez courant, un capteur de lumière pour entre autres régler la luminosité de l'appareil en fonction de la lumière ambiante et un capteur de distance qui est par exemple utilisé lorsque vous approchez votre téléphone de votre oreille pour éteindre l'écran.

L'interface ressemble beaucoup à celle de l'iPhone.
Voici quelques screens de mon interface (j'ai changé le thème par défaut) :

(le but du jeu ici est de glisser le Cadenas au milieu de l'écran pour déverouiller l'appareil).

Et voici des screens de la future interface :

Je tenterais de vous faire une vidéo dès que j'en aurais l'occasion pour vous montrer la réactivité de l'affaire.

Parlons € maintenant. La bête en version 8Go est vendue 2000 yuan (~200€) et 2300 yuan (~230€) pour la version 16go.

Les prix indiqués sont donc pour une version nue débloquée.

Ce téléphone est trouvable sur plusieurs boutiques en ligne mais à des prix assez élevés, il est par contre possible de le trouver à 250-300€ il me semble.
J'ai acheté le mien en Mai en Chine (pour 2000 yuan) et je peux vous dire que j'en suis très très content malgrè les quelques bugs du firmware. J'attends donc la version 1.0 avec impatience.

Meizu aurait aussi communiqué sur une future version embarquant une puce GPS...
Je pense sincèrement que ce téléphone pourrait trouver des nombreux acquéreurs en Europe et même aux Etats-Unis si un distributeur avait la courage de se lancer (en vérifiant tout de même si le téléphone ne viole pas de brevets...).

Une communauté s'est également formé autour de ce téléphone, fournissant bon nombres de ressources (applications, thèmes...).
http://www.meizume.com/forums.php

Voilà si vous avez des questions sur ce téléphone je suis là pour y répondre.

Que pensez-vous de ce téléphone ?

Problème avec la mise à jour KB971092

Ce matin après avoir installé la mise à jour pour Visual Studio KB971092 et après avoir rebooté mon PC, Windows Update me signale qu’une MàJ est disponible, je regarde et c’est encore ce même KB. Je réinstalle donc sans aucun soucis et quelques secondes après Windows Update me signale de nouveau une MàJ, encore et toujours pour le même KB.

Si vous aussi vous avez ce problème, sachez qu’il existe une solution que je traduis pour les anglophobes :

  1. Téléchargez la mise à jour à partir du site de MS (http://www.microsoft.com/downloads/details.aspx?displaylang=en&FamilyID=294de390-3c94-49fb-a014-9a38580e64cb)
  2. Lancez VS90SP1-KB971092-x86.exe et lorsque le message d’erreur apparait, ne fermez pas la fenêtre
  3. Copiez le répertoire temporaire où le patch a été extrait
  4. Fermez l’installation lancée en 2
  5. Lancez VS90SP1-KB971092-x86.msp à partir du répertoiré collé en 3
  6. Et voilà ça fonctionne

Un autre problème peut survenir comme quoi le fichier vsvars32.bat ne peut être ouvert, si c’est le cas, allez dans <drive>:\Program Files\Microsoft Visual Studio 9.0\Common7\Tools et éditez les autorisations du fichier afin d’autoriser tout le monde à écrire dedans.

Liens :
http://weblogs.asp.net/guybarrette/archive/2009/07/29/kb971092-fails-to-install.aspx
https://connect.microsoft.com/VisualStudio/feedback/Workaround.aspx?FeedbackID=478117

Et c’est parti pour Silverlight 3 !

Et oui le moment attendu vient d’arriver : la version 3 de Silverlight est disponible au téléchargement.

Ce lancement est passé tout de même assez inaperçu, je n’ai pas encore un seul billet de blog qui en parle dans mes RSS ! Serais-je le premier dans la blogosphère ?

Enfin bref voici tous les liens qu’il vous faut :

Je tâcherai des faire quelques articles sur les nouveautés !

Have fun :)

[ASP.NET AJAX] Traduction des 56 tutoriels officiels

Comme annoncé dans un précédent billet, l’équipe de Developpez.com vient de traduire les 56 tutoriels officiels sur ASP.NET AJAX.

Beaucoup de chose sont au programme, je vous laisse les découvrir par vous-même.

56 tutoriels pour maîtriser l'AJAX au sein d'ASP.NET

Bonne lecture !

Disponibilité de Silverlight 3 : la date

silverlight Il semblerait que Microsoft vienne d’annoncer la date de disponibilité de Silverlight 3 ainsi que de la gamme Expression 3. Il s’agirait du 10 juillet.

Un évènement serait par ailleurs prévu dans la Bay Area (San Francisco je suppose). Et c’est là que je suis complètement déçu : je quitte San Francisco le 1 juillet pour rentrer en France :(

Une version RC devrait quant à elle voir le jour le mois prochain.

Pour les nouveautés de Silverlight 3, je vous laisse jeter un oeil sur un de mes posts un peu plus bas.

Je confirmerai ou pas cette date un peu plus tard…

[Silverlight][Fun] Logo Silverlight

Dans la catégorie posts inutiles, voici celui du mois :

11010100000110000010101010100111001001101110111101000010001110010001010110101100
01010000111110100010111011101001110111011101101000001011101111000001001000001111
11000010100110011001111101100110000111000000000101110010011000111011000111001000
00001010101010000011110110110001111010001011111000111001100100010111011000010110
01011000111110001111110100001011100101000011101100000000101110111110111001010001
10000100010001101001101101110000000111101011010100101110100111100101001111110011
01101101101000111101100010001000000011000110110101010010010001000101010011010101
01010110111110000011110111101001111001110011011011000100101111100100001101001111
11101111011100000001000000101011011101100100111100100111110100010000110101001011
11111011011001100101010000010000111110101001010011010011001111010110110011111011
00110111010100001101000011000110100111101000001111101100000110000101000011111100
00011001011110011100001101010110100100001011101000111110010101101001001010101001
01001000111001100000101001000101011110011011110110101111001010110100110001110100
00000110101001110000011000100011011101100110110101110010101011100010111100001000
11111110010011101111000101000111011000000100000101000111000000010001010101110000
01001010100101100101011101001111001111110000101110101010100010101101010100011010
11000011001010010100010111001001101000000011110110111001111100101010001011011001
00001000110101100111010001011101001001001000100101001010111100101001100000100000
01110100101010111001000110010010011001001111000110010110101100011000001110101111
10001000001110110110111011000000010110110011011001011100011010100111001000111101
11000100011100000111100100000011001001011001111100010010001001110100110110100001
01100101110001010010000110000010101011110001010001110010001000100001010011101110
11100100110000100110101001101000010100100101001000100100001000110011011000100100
00101011010000010100100111111100110011101000110100100101010110010101010101001011
00100101000101000111101100000010001001000010111110100011110110000000110111101101
00010010100001101010100101001011001111101011111110111110001000000110110001101111
00000110011010101001010011010111100010110100100010100010111101001111010000000101
10000111111000000010001011001001001101110100110100000110011001010001011011001110
00101001110111100101000011000011010001101001000100110001011011110011100011100111
00011111100110001011110001001100100101010010111001110000111100010111100000000110
11001011011110011001000011011010100101000110000000110100010111010111101010110110
10100100000000111110010100110001111111101100111110001011010011001000001010100001
00001011110111001011010010100011000101011010111011100100110010101110100011011110
01111101000101001110000110111101110001111100110010001000010110010011011000100101
00111011001111010110001001001100100100001110011011101110111110010001110010000010
00110100011101010100111111010100101110011100111001001101011111011001010111011101
10011011110101101101011100100100101100101010111011010000101100100101000011000011
00100000101101000101100001100001010110101000101110001011000000000000110100111101
11111010011010011000101100000110001011110011100000111001100010110011101101110011
11111100011010101101111011100100101110000100110010101010000100111001001111011001
00000001101010001110100011110001000111110110011111000101100011001011111110001110
00010100101000100000110101101011010101001100100110111100011101010100001011111011
11000001111000010011100101011011010000011001111110000100110110110100011001110000
10110111111011010000000010100011000010111100100101110001101011100001101100010011
11000100101011100100000010110000101010100100111001011010101000010000101110101101
00011110111001000001100100110111011110001110010110100100100000110100111001000100
01010100001110111110111000001001111000111001011011

:)

[Silverlight] Proof of Concept : Paint

silverlight Bonjour à tous,

Je viens de retrouver un projet, sur mon disque dur, que j’avais commencé il y a presque 2 ans déjà. Il s’agit d’un Paint en Silverlight reprenant les principales fonctionnalités de ce dernier.

La première version était en Silverlight 1.1 (oui oui l’alpha où on pouvait rien faire) puis je l’avais porté en SL2 Beta 1 et maintenant en SL2 RTW. Le concept n’est pas bien compliqué mais c’était marrant à faire, surtout en 1.1.

slpaintVoilà si vous voulez jeter un oeil aux sources ou vous amuser avec voici quelques liens :

http://broux.developpez.com/public/SL/Paint/PaintOnline.zip 

http://broux.developpez.com/public/SL/Paint/PaintOnlineTestPage.html

Peut-être qu’il est possible de faire un projet marrant avec, mais là j’ai pas d’idées donc si vous en avez, go commentaires :) !

[Silverlight] Gestion du menu contextuel

silverlight Bonjour à tous,

Une question qui revient souvent sur les forums dédiés à Silverlight est la gestion du menu contextuel (clic droit). La réponse actuelle est qu’il n’est pas possible nativement de surcharger les menu contextuel à la manière de Flash. Il semblerait qu’il faille attendre une future version de Silverlight…

En revanche je vais ici vous montrer une solution “passable” permettant de passer outre le clic droit classique. Il faut savoir que le code suivant fonctionne correctement sous IE mais pose quelques soucis sous Firefox. En effet, sous ce dernier, le menu classique s’affiche suivi du menu custom. Si quelqu’un connait une solution il peut se manifester dans les commentaires.

Pour rendre le tout facilement utilisable j’ai créé une classe RightClickService permettant de créer facilement des menu contextuels pour toute sorte de contrôle.

Tout d’abord voici le ContextMenuItem et le ContextMenu.

[TemplateVisualState(Name = "Normal", GroupName = "CommonStates"),
TemplateVisualState(Name = "Focused", GroupName = "FocusStates"),
TemplateVisualState(Name = "MouseOver", GroupName = "CommonStates"),
TemplateVisualState(Name = "Disabled", GroupName = "CommonStates"),
TemplateVisualState(Name = "Unselected", GroupName = "SelectionStates"),
TemplateVisualState(Name = "Selected", GroupName = "SelectionStates"),
TemplateVisualState(Name = "SelectedUnfocused", GroupName = "SelectionStates"),
TemplateVisualState(Name = "Unfocused", GroupName = "FocusStates")]
public class ContextMenuItem : ContentControl
{
    public event MouseButtonEventHandler Click;
 
    public ContextMenuItem()
    {
        this.DefaultStyleKey = typeof(ContextMenuItem);
        this.MouseLeftButtonDown += delegate(object sender, MouseButtonEventArgs e)
        {
            if (Click != null) Click(this, e);
        };
    }
 
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
        VisualStateManager.GoToState(this, "Normal", false);
    }
 
    protected override void OnMouseLeftButtonUp(MouseButtonEventArgs e)
    {
        if (!e.Handled)
        {
            base.OnMouseLeftButtonUp(e);
            e.Handled = true;
            if (RightClickService.Popup != null) RightClickService.Popup.IsOpen = false;
        }
    }
 
    protected override void OnMouseEnter(MouseEventArgs e)
    {
        base.OnMouseEnter(e);
        VisualStateManager.GoToState(this, "MouseOver", false);
    }
 
    protected override void OnMouseLeave(MouseEventArgs e)
    {
        base.OnMouseLeave(e);
        VisualStateManager.GoToState(this, "Normal", false);
    }
}

Il s’agit tout simplement d’un contrôle simple ressemblant à un ListBoxItem. J’ai également créé un event Click se déclanchant lors d’un MouseLeftButtonDown.

La thème du contrôle est le suivant :

<ResourceDictionary
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:local="clr-namespace:ContextMenu"    
  xmlns:vsm="clr-namespace:System.Windows;assembly=System.Windows">
    <Style TargetType="local:ContextMenu">
        <Setter Property="Padding" Value="1"/>
        <Setter Property="Background" Value="#FFFFFFFF" />
        <Setter Property="Foreground" Value="#FF000000"/>
        <Setter Property="HorizontalContentAlignment" Value="Left" />
        <Setter Property="VerticalContentAlignment" Value="Top" />
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="BorderThickness" Value="1" />
        <Setter Property="TabNavigation" Value="Once" />
        <Setter Property="BorderBrush">
            <Setter.Value>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FFA3AEB9" Offset="0"/>
                    <GradientStop Color="#FF8399A9" Offset="0.375"/>
                    <GradientStop Color="#FF718597" Offset="0.375"/>
                    <GradientStop Color="#FF617584" Offset="1"/>
                </LinearGradientBrush>
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:ContextMenu">
                    <Border CornerRadius="2" 
                            BorderBrush="{TemplateBinding BorderBrush}"
                            BorderThickness="{TemplateBinding BorderThickness}">
                        <ItemsPresenter />
                    </Border>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
 
    <Style TargetType="local:ContextMenuItem">
        <Setter Property="Padding" Value="3" />
        <Setter Property="HorizontalContentAlignment" Value="Left" />
        <Setter Property="VerticalContentAlignment" Value="Top" />
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="BorderThickness" Value="1"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="local:ContextMenuItem">
                    <Grid Background="{TemplateBinding Background}">
                        <vsm:VisualStateManager.VisualStateGroups>
                            <vsm:VisualStateGroup x:Name="CommonStates">
                                <vsm:VisualState x:Name="Normal" />
                                <vsm:VisualState x:Name="MouseOver">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="fillColor" Storyboard.TargetProperty="Opacity" Duration="0" To=".35"/>
                                    </Storyboard>
                                </vsm:VisualState>
                                <vsm:VisualState x:Name="Disabled">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="contentPresenter" Storyboard.TargetProperty="Opacity" Duration="0" To=".55" />
                                    </Storyboard>
                                </vsm:VisualState>
                            </vsm:VisualStateGroup>
                            <vsm:VisualStateGroup x:Name="SelectionStates">
                                <vsm:VisualState x:Name="Unselected" />
                                <vsm:VisualState x:Name="Selected">
                                    <Storyboard>
                                        <DoubleAnimation Storyboard.TargetName="fillColor2" Storyboard.TargetProperty="Opacity" Duration="0" To=".75"/>
                                    </Storyboard>
                                </vsm:VisualState>
                            </vsm:VisualStateGroup>
                            <vsm:VisualStateGroup x:Name="FocusStates">
                                <vsm:VisualState x:Name="Focused">
                                    <Storyboard>
                                        <ObjectAnimationUsingKeyFrames Storyboard.TargetName="FocusVisualElement" Storyboard.TargetProperty="Visibility" Duration="0">
                                            <DiscreteObjectKeyFrame KeyTime="0">
                                                <DiscreteObjectKeyFrame.Value>
                                                    <Visibility>Visible</Visibility>
                                                </DiscreteObjectKeyFrame.Value>
                                            </DiscreteObjectKeyFrame>
                                        </ObjectAnimationUsingKeyFrames>
                                    </Storyboard>
                                </vsm:VisualState>
                                <vsm:VisualState x:Name="Unfocused"/>
                            </vsm:VisualStateGroup>
                        </vsm:VisualStateManager.VisualStateGroups>
                        <Rectangle Fill="LightGray" IsHitTestVisible="False" RadiusX="1" RadiusY="1" />
                        <Rectangle x:Name="fillColor" Opacity="0" Fill="#FFBADDE9" IsHitTestVisible="False" RadiusX="1" RadiusY="1"/>
                        <Rectangle x:Name="fillColor2" Opacity="0" Fill="#FFBADDE9" IsHitTestVisible="False" RadiusX="1" RadiusY="1"/>
                        <ContentPresenter
                    x:Name="contentPresenter"
                    Content="{TemplateBinding Content}"
                    ContentTemplate="{TemplateBinding ContentTemplate}"
                    HorizontalAlignment="Left"
                    Margin="{TemplateBinding Padding}"/>
                        <Rectangle x:Name="FocusVisualElement" Stroke="#FF6DBDD1" StrokeThickness="1" Visibility="Collapsed" RadiusX="1" RadiusY="1" />
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
 
</ResourceDictionary>

Le ContextMenu :

public class ContextMenu : ItemsControl
{
    public ContextMenu()
    {
        base.DefaultStyleKey = typeof(ContextMenu);
    }
 
    public override void OnApplyTemplate()
    {
        base.OnApplyTemplate();
    }
 
    protected override DependencyObject GetContainerForItemOverride()
    {
        return new ContextMenuItem();
    }
 
    protected override bool IsItemItsOwnContainerOverride(object item)
    {
        return (item is ContextMenuItem);
    }
}

Ce contrôle hérite de ItemsControl, et surcharge les méthodes GetContainerForItemOverride et IsItemItsOwnContainerOverride pour définir le contrôle à utiliser pour l’affichage si on n’utilise pas directement un ContextMenuItem.

Voici maintenant la classe utile : RightClickService.

public class RightClickService
{
    private static FrameworkElement mRootVisual = null;
 
    internal static FrameworkElement RootVisual
    {
        get
        {
            SetRootVisual();
            return mRootVisual;
        }
    }
 
    private static void SetRootVisual()
    {
        if (mRootVisual == null && Application.Current != null)
        {
            mRootVisual = Application.Current.RootVisual as FrameworkElement;
        }
    }
 
    #region Attached Property
 
    public static readonly DependencyProperty ContextMenuProperty =
        DependencyProperty.RegisterAttached("ContextMenu", typeof(ContextMenu), typeof(RightClickService), null);
 
    public static void SetContextMenu(UIElement element, ContextMenu value)
    {
        element.SetValue(ContextMenuProperty, value);
    }
    public static ContextMenu GetContextMenu(UIElement element)
    {
        return (ContextMenu)element.GetValue(ContextMenuProperty);
    }
 
    #endregion
 
    static RightClickService()
    {
        if (Application.Current.Host.Settings.Windowless == false) throw new Exception("Your SL plugin must be initialize with Windowless to true");
 
        if (HtmlPage.IsEnabled) HtmlPage.Document.AttachEvent("oncontextmenu", RightClickService.OnContextMenu);
    }
 
    private static void OnContextMenu(object sender, HtmlEventArgs e)
    {
        IEnumerable<UIElement> elements = GetControls(e.OffsetX, e.OffsetY);
 
        if (elements != null)
        {
            foreach (UIElement element in elements)
            {
                ContextMenu menu = RightClickService.GetContextMenu(element);
 
                if (menu != null)
                {
                    PerformPlacement(menu, e.OffsetX, e.OffsetY);
                    break;
                }
            }
        }
 
        e.PreventDefault();
    }
 
    internal static Popup Popup { get; set; }
 
    private static void PerformPlacement(FrameworkElement content, int x, int y)
    {
        Canvas elementOutside = new Canvas();
        Canvas childCanvas = new Canvas();
 
        elementOutside.Background = new SolidColorBrush(Colors.Transparent);
 
        if (Popup != null)
        {
            Popup.IsOpen = false;
            if (Popup.Child is Canvas) ((Canvas)Popup.Child).Children.Clear();
        }
        Popup = new Popup();
 
        Popup.Child = childCanvas;
 
        elementOutside.MouseLeftButtonDown += new MouseButtonEventHandler((o, e) => Popup.IsOpen = false);
        elementOutside.Width = Application.Current.Host.Content.ActualWidth;
        elementOutside.Height = Application.Current.Host.Content.ActualHeight;
 
        childCanvas.Children.Add(elementOutside);
        childCanvas.Children.Add(content);
 
        Canvas.SetLeft(content, x);
        Canvas.SetTop(content, y);
 
        Popup.IsOpen = true;
    }
 
    private static IEnumerable<UIElement> GetControls(int x, int y)
    {
        return VisualTreeHelper.FindElementsInHostCoordinates(new Point(x, y), RootVisual);
    }
}

Il suffit simplement passer par l’évènement Javascript oncontextmenu.

Afin de spécifier le menu contextuel de chaque contrôle je passe par une attached property. Lorsque le clic droit est détecté je récupère tout d’abord le contrôle en utilisant les coordonnée de la souris et le VisualTreeHelper, puis le menu associé au contrôle. J’affiche ensuite le menu dans un Popup.

Petite astuce : j’utilise un canvas invisible faisant toute la taille de l’application permettant de fermer le menu lorsque l’utilisateur clique en dehors de celui-ci.

C’est terminé pour le contrôle.

L’utilisation est assez simple.

<UserControl x:Class="TestSilverlight.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:cm="clr-namespace:ContextMenu;assembly=ContextMenu"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <Image Source="silverlight.png">
            <cm:RightClickService.ContextMenu>
                <cm:ContextMenu>
                    <cm:ContextMenuItem Content="Save As" Click="SaveImage" />
                    <cm:ContextMenuItem Content="View Image" Click="ViewImage" />
                </cm:ContextMenu>
            </cm:RightClickService.ContextMenu>
        </Image>
    </Grid>
</UserControl>

Je rappelle juste que ce code ne fonctionne pas extrêmement bien sous Firefox.

Voici le lien pour les sources.

Have fun :)

[Silverlight] Une image affichant sa progression

silverlight Bonjour à tous,

J’avoue le titre n’est peut-être pas très explicite, mais dans ce post nous allons voir comment créer une image affichant le fameux sablier du post précédent tant que cette dernière n’est pas chargée.

On crée tout d’abord notre XAML composé en tout et pour tout de deux contrôles : une Image et un Loading.

<UserControl x:Class="Sky.Controls.ImageProgress"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:Sky.Controls">
    <Grid x:Name="LayoutRoot" Background="White">
        <Image x:Name="Image" Stretch="Fill" />
        <local:Loading x:Name="Buffer" />
    </Grid>
</UserControl>

Tout le reste va être réalisé en C#.

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media.Imaging;
 
namespace Sky.Controls
{
    public partial class ImageProgress : UserControl
    {
        public ImageProgress()
        {
            InitializeComponent();
        }
 
        public BitmapImage Source
        {
            get { return (BitmapImage)GetValue(SourceProperty); }
            set
            {
                SetValue(SourceProperty, value);
                value.DownloadProgress += new EventHandler<DownloadProgressEventArgs>(value_DownloadProgress);
                this.Image.Source = value;
                this.BeginAnimation();
            }
        }
 
        void value_DownloadProgress(object sender, DownloadProgressEventArgs e)
        {
            if (e.Progress == 100)
            {
                StopAnimation();
            }
        }
 
        // Using a DependencyProperty as the backing store for Source.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty SourceProperty =
            DependencyProperty.Register("Source", typeof(BitmapImage), typeof(ImageProgress), new PropertyMetadata(new PropertyChangedCallback(OnSourceChanged)));
 
        private static void OnSourceChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
        {
            ImageProgress source = sender as ImageProgress;
            if (source != null) source.Source = (BitmapImage)e.NewValue;
        }
 
        private void BeginAnimation()
        {
            this.Buffer.Start();
        }
 
        private void StopAnimation()
        {
            this.Buffer.Stop();
            this.Buffer.Visibility = Visibility.Collapsed;
        }
    }
}

Rien de bien compliqué. Tout d’abord on crée une DP pour la Source de notre Image. Lorsque cette DP est modifiée on lance le téléchargement de notre image et on affiche notre sablier. Lorsque le téléchargement est terminé, on le cache, tout simplement.

Ce petit contrôle s’avère très utile dans des applications affichant un certains nombres d’images venant de sources extérieures.

On pourrait également checker l’evènement ImageFailed du contrôle Image afin d’afficher une image d’erreur si la source n’est pas disponible.

Have fun !

[Silverlight] Un contrôle type sablier

silverlight Bonjour à tous,

Aujourd’hui je vais vous présenter un contrôle assez pratique, puisqu’il s’agit d’un contrôle type sablier sous Windows Vista. Ce contrôle permet de signifier à l’utilisateur qu’une action est en train de se passer.

 loading

Le code pour réaliser ce contrôle est assez simple. Une ellipse à laquelle on anime le GradientBrush de son Stroke.

<UserControl x:Class="Sky.Controls.Loading"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <UserControl.Resources>
        <Storyboard x:Name="Animation" RepeatBehavior="Forever">
            <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Shape.Stroke).(LinearGradientBrush.StartPoint)">
                <SplinePointKeyFrame KeyTime="00:00:00.2500000" Value="0.846,0.139"/>
                <SplinePointKeyFrame KeyTime="00:00:00.5000000" Value="1,0.491"/>
                <SplinePointKeyFrame KeyTime="00:00:00.7500000" Value="0.869,0.838"/>
                <SplinePointKeyFrame KeyTime="00:00:01" Value="0.494,1"/>
                <SplinePointKeyFrame KeyTime="00:00:01.2500000" Value="0.167,0.873"/>
                <SplinePointKeyFrame KeyTime="00:00:01.5000000" Value="0,0.494"/>
                <SplinePointKeyFrame KeyTime="00:00:01.7500000" Value="0.146,0.146"/>
                <SplinePointKeyFrame KeyTime="00:00:02" Value="0.494,-0.001"/>
            </PointAnimationUsingKeyFrames>
            <PointAnimationUsingKeyFrames BeginTime="00:00:00" Storyboard.TargetName="ellipse" Storyboard.TargetProperty="(Shape.Stroke).(LinearGradientBrush.EndPoint)">
                <SplinePointKeyFrame KeyTime="00:00:00.2500000" Value="0.154,0.861"/>
                <SplinePointKeyFrame KeyTime="00:00:00.5000000" Value="0,0.509"/>
                <SplinePointKeyFrame KeyTime="00:00:00.7500000" Value="0.131,0.162"/>
                <SplinePointKeyFrame KeyTime="00:00:01" Value="0.506,0"/>
                <SplinePointKeyFrame KeyTime="00:00:01.2500000" Value="0.833,0.127"/>
                <SplinePointKeyFrame KeyTime="00:00:01.5000000" Value="1,0.506"/>
                <SplinePointKeyFrame KeyTime="00:00:01.7500000" Value="0.854,0.854"/>
                <SplinePointKeyFrame KeyTime="00:00:02" Value="0.506,1.001"/>
            </PointAnimationUsingKeyFrames>
        </Storyboard>
    </UserControl.Resources>
    <Grid x:Name="LayoutRoot" Background="Transparent">
        <Ellipse Width="25" Height="25" StrokeThickness="5.5" x:Name="ellipse">
            <Ellipse.Stroke>
                <LinearGradientBrush EndPoint="0.5,1" StartPoint="0.5,0">
                    <GradientStop Color="#FF096475" Offset="0.571"/>
                    <GradientStop Color="#FFA8FCFC" Offset="1"/>
                </LinearGradientBrush>
            </Ellipse.Stroke>
        </Ellipse>
    </Grid>
</UserControl>

Finalement une pointe de C#, pour lancer et arrêter l’animation.

public void Start()
{
    this.Animation.Begin();
}
 
public void Stop()
{
    this.Animation.Stop();
}

Le résultat est assez agréable à voir. Libre à vous de changer les couleurs.

Have fun !

[ASP.NET MVC] Traduction des 38 tutoriels officiels

L’équipe .NET de Developpez.com, dont je fais partie, vient de traduire les 38 tutoriels officiels sur ASP.NET MVC.

Au programme :

  • Présentation d'ASP.NET MVC
  • Le routing
  • Les Contrôleurs
  • Les Vues
  • Les Modèles
  • La validation
  • Master Pages
  • Les filtres d'actions
  • Améliorer les performances avec le caching
  • Sécurité
  • Testing
  • Navigation
  • Le déploiement
  • Développement d’une application de gestion de contacts avec ASP.NET MVC

38 tutoriels pour maîtriser ASP.NET MVC

Nous préparons également la traduction des quelques 46 tutoriels sur ASP.NET AJAX.

Bonne lecture !

[Silverlight] Votez pour mon jeu

Bonjour tout le monde.

Aujourd’hui pas d’astuces ou de news sur Silverlight, mais simplement une petite demande d’entraide.

Je participe à un concours sur le développement d’un jeu en Silverlight, j’ai donc réalisé le mien qui se trouve dans les 16 finalistes. Le reste des votes est fait par les visiteurs.

J’écris donc ce post afin de demander à tout le monde de voter pour moi, dans la mesure où mon jeu vous plait bien évidemment. Comme dit dans la description, je n’ai strictement aucun talent des graphiste, mon jeu est donc assez basique à ce niveau là.

Pour voter pour moi, il suffit simplement de se rendre sur cette page http://www.serverquestcontest.com/register.aspx afin de s’enregistrer (les informations, adresses mails ne sont pas vérifiées) puis d’aller sur cette page http://www.serverquestcontest.com/game.aspx?GID=30 afin de tester et de voter pour mon jeu.

Je remercie toutes les personnes qui prendront quelques minutes de leur temps pour moi :)

Plus de Messages Page suivante »


Les 10 derniers blogs postés

- TechDays Paris 2010 : La BI dans SharePoint 2010 par Blog Technique de Romelard Fabrice le il y a 2 heures et 7 minutes

- TechDays Paris 2010 : Déploiement de nouvelles technologies – Retour d’expérience par l’informatique de Microsoft par Blog Technique de Romelard Fabrice le il y a 3 heures et 34 minutes

- TechDays Paris 2010 : Plan de migration vers SharePoint 2010 par Blog Technique de Romelard Fabrice le il y a 7 heures et 16 minutes

- TechDays Paris 2010 : La pleinière du second jour par Blog Technique de Romelard Fabrice le il y a 8 heures et 21 minutes

- Visual Studio 2010 and .NET Framework 4 Release Candidate now available par Matthieu MEZIL le il y a 11 heures et 27 minutes

- Création d’une base de donnée sous SQL Azure par Le Blog (Vert) d'Arnaud JUND le il y a 12 heures et 24 minutes

- TechDays Paris 2010 : Les Services d’applications dans SharePoint 2010 par Blog Technique de Romelard Fabrice le il y a 22 heures et 23 minutes

- TechDays Paris 2010 : La GED et SharePoint 2010 par Blog Technique de Romelard Fabrice le 02-08-2010, 16:54

- TechDays Paris 2010 : SharePoint 2010 et Les réseaux sociaux par Blog Technique de Romelard Fabrice le 02-08-2010, 15:40

- TechDays Paris 2010 : SharePoint 2010 – Description et nouveautés par Blog Technique de Romelard Fabrice le 02-08-2010, 14:33