Archive for October, 2010

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.

      Sortie officielle de Windows Phone 7

      Aucun commentaire

        Steve Ballmer et Ralph de la Vega, President & CEO de AT&T Mobility, ont annoncé pour le 21 Octobre la sortie mondiale à la vente de Windows Phone 7. Comme l'on pouvait s'y attendre au vu des précédentes annonces, 3 opérateurs historiques français ainsi que 5 constructueurs sont concernés, pas d'exclusivité en vue. A noter que windows Phone 7 contient une version de office mobile spécialement conçu pour l'OS. Le premier device mobile Windows Phone 7 sera disponible au prix de 29 euros. Pour avoir une vue globale de la plateforme WP7, vous pouvez vous référer à la conférence des teched Microsoft que vous trouverez ici. En attendant de l'avoir entre les mains, quelques devices sont sur les rangs, le Omnia 7 de Samsung, le Optimus 7 de LG et pour complètement innover le HTC HD7; c'est ce dernier qui présente le design le plus épuré avec son large écran de 4,7".