# Thursday, June 03, 2010

Etre notifié du changement de valeur d’une DependencyProperty

Les contrôles n’implémentent pas tous des événements notifiant du changement de valeur de leurs propriétés. Un moyen d’être notifié est d’utiliser le Binding. Voici une classe fournissant des méthodes d’extensions sur les DependencyObject pour ajouter des handlers d’événements.

Ajouter un événement très simple :

            ScrollBar sb = new ScrollBar();

            sb.AddChangedHandler("Value", (o, e) =>

            {

                MessageBox.Show(Convert.ToString(e.NewValue));

            });

Code :

    public static class DependencyObjectExtensions

    {

        /// <summary>

        /// Inner class bound to the Property we want to monitor

        /// </summary>

        private class BindingSubscription : DependencyObject, IDisposable

        {

            /// <summary>

            /// Constructor

            /// </summary>

            /// <param name="source">The DependencyObject instance on which we want to monitor the property</param>

            /// <param name="name">The PropertyPath to the property we want to monitor</param>

            /// <param name="handler">The handler to invoke when the property changed</param>

            public BindingSubscription(DependencyObject source, string name, DependencyPropertyChangedEventHandler handler)

            {

                this.Handler = handler;

                binding = new Binding(name) { Source = source };

                this.PropertyPath = name;

                BindingOperations.SetBinding(this, ValueProperty, binding);

            }

 

            private Binding binding;

 

            /// <summary>

            /// The PropertyPath to the property we want to monitor

            /// </summary>

            public string PropertyPath { get; set; }

 

            /// <summary>

            /// The handler to invoke when the property changed

            /// </summary>

            public DependencyPropertyChangedEventHandler Handler { get; set; }

 

            /// <summary>

            /// Value depedency property.

            /// </summary>

            public static readonly DependencyProperty ValueProperty =

                DependencyProperty.Register(

                    "Value",

                    typeof(object),

                    typeof(BindingSubscription),

                    new PropertyMetadata((d, e) =>

                    {

                        var subscription = ((BindingSubscription)d);

                        var handler = subscription.Handler;

                        if (handler != null)

                            handler(subscription.source, e);

                    }));

 

            /// <summary>

            /// Release the binding from the source

            /// </summary>

            public void Dispose()

            {

                this.ClearValue(ValueProperty);

            }

        }

 

        /// <summary>

        /// Get the list of BindingSubscription stored on one object

        /// </summary>

        /// <param name="obj"></param>

        /// <returns></returns>

        private static List<BindingSubscription> GetListeners(DependencyObject obj)

        {

            var list = (List<BindingSubscription>)obj.GetValue(ListenersProperty);

            if (list == null)

            {

                list = new List<BindingSubscription>();

                SetListeners(obj, list);

            }

            return list;

        }

 

        /// <summary>

        /// Set the list of BindingSubscription on an object

        /// </summary>

        /// <param name="obj"></param>

        /// <param name="value"></param>

        private static void SetListeners(DependencyObject obj, List<BindingSubscription> value)

        {

            obj.SetValue(ListenersProperty, value);

        }

 

 

        /// <summary>

        /// Listeners dependency property

        /// </summary>

        private static readonly DependencyProperty ListenersProperty =

            DependencyProperty.RegisterAttached("Listeners", typeof(List<BindingSubscription>), typeof(DependencyObjectExtensions), null);

 

 

        /// <summary>

        /// Add a handler to a DependencyProperty for change notification

        /// </summary>

        /// <param name="source">The DependencyObject instance on which we want to monitor the property</param>

        /// <param name="name">The PropertyPath to the property we want to monitor</param>

        /// <param name="handler">The handler to invoke when the property changed</param>

        public static void AddChangedHandler(this DependencyObject source, string name, DependencyPropertyChangedEventHandler handler)

        {

            // Create the binding

            BindingSubscription subscriber = new BindingSubscription(source, name, handler);

            // Store the binding into de DependencyObject to prevent garbage collection of the subscriber

            GetListeners(source).Add(subscriber);

        }

 

        /// <summary>

        /// Remove a handler from a DependencyProperty

        /// </summary>

        /// <param name="source">The DependencyObject instance on which we want to monitor the property</param>

        /// <param name="name">The PropertyPath to the property we want to monitor</param>

        /// <param name="handler">The handler to invoke when the property changed</param>

        public static void RemoveChangedHandler(this DependencyObject source, string name, DependencyPropertyChangedEventHandler handler)

        {

            var subscribers = GetListeners(source);

            var subscriber = subscribers.FirstOrDefault(s => s.Handler == handler && s.PropertyPath == name);

            if (subscriber != null)

            {

                subscriber.Dispose();

                subscribers.Remove(subscriber);

            }

 

            if (subscribers.Count == 0)

                source.ClearValue(ListenersProperty);

        }

    }

#    Comments [0] |
# Thursday, February 21, 2008

XamlTune Live

xamltuneA live version of xamltune has been released on our web site. This tool is intensively used by our development team. Svg graphics are converted in Xaml and the result can be optimized in several ways.

XamlTune sources and binaries can be downloaded on the codeplex page.

Live version can be tested in our labs area.

#    Comments [0] |
# Friday, February 08, 2008

XamlTune on CodePlex

XamlTune is now on codeplex. Have fun.
Untitled
#    Comments [2] |
# Wednesday, February 06, 2008

VisioExportToXAML

Saveen Reddy has released his visio export plugin on codeplex. He is using my XamlTune export library.

I've corrected XamlTune to render its last sample.
Untitled

#    Comments [0] |
# Saturday, December 08, 2007

Convertion Svg vers Xaml

XamlTune Si la plateforme .Net supportant le Xaml est gratuite, il n'en est pas de même des outils pour développer pour cette plateforme. Je ne parle pas ici du code, mais de quoi faire du desin Xaml. Pour transformer du svg en xaml, il n'existe que peu de logiciels.
WPF-Graphics - Paste2Xaml is a clipboard or metafiles into xaml
et Adobe Illustrator to XAML Export à ma connaissance. Je vous propose ici un petit utilitaire libre de droits pour générer faire ce travail. Il est basé sur SharpVector pour lire le svg et génère du xaml pour wpf ou silverlight. Je mets au passage le lien vers InkScape qui permet de travailler les fichiers svg.

Mise à jour 2007/12/13: Corrections sur les dégradés radiaux. La case à cocher "Canvas as Path Bounding box" reste encore buggué.

Mise à jour 2007/12/15: Ajout de textbox de visualisation et d'édition du svg/xaml. Corrections de bugs. Ajout d'un treeview de visualisation des éléments xaml.

Télécharger

#    Comments [0] |
# Friday, December 07, 2007

Blend 2 December Preview et Blend sp1

boxShot_Blend Une nouvelle CTP de Blend 2 est disponible sur le site de Microsoft. Quelques corrections de bugs et le support des solutions VS2008 RTM.

Téléchargement : Blend 2
Blend sp1

#    Comments [0] |
# Tuesday, October 16, 2007

Réalité augmentée


Petite démonstration sympa. Il faudra que je me penche la dessus un jour, ça a l'air sympa.
#    Comments [0] |