Beispiel #1
0
        private static long TestCompiled()
        {
            DataTestForPerf src = new DataTestForPerf();
            DataTestForPerf dst = new DataTestForPerf();

            PropertyInfo piSource = src.GetType().GetProperty("Prop1");
            PropertyInfo piDest   = dst.GetType().GetProperty("Prop1");

            GetHandlerDelegate <int> getSrc = GetSetUtils.CreateGetHandler <int>(piSource);
            SetHandlerDelegate <int> setDst = GetSetUtils.CreateSetHandler <int>(piDest);

            src.PropertyChanged += delegate
            {
                setDst(dst, getSrc(src));
            };

            Stopwatch watch = new Stopwatch();

            watch.Start();
            for (int i = 1; i <= NBTURNS; i++)
            {
                src.Prop1 = i;
            }
            watch.Stop();
            return(watch.ElapsedMilliseconds);
        }
Beispiel #2
0
        public void Bind(object source, PropertyInfo piSource, object destination,
                         PropertyInfo piDest,
                         IBinderConverter converter,
                         SynchronizationContext applyBindingContext)
        {
            weakSrc         = new WeakReference(source);
            weakDst         = new WeakReference(destination);
            _Converter      = converter;
            _PropNameSource = piSource.Name;
            _PropNameDest   = piDest.Name;
            gethandler      = GetSetUtils.CreateGetHandler <TValueSource>(piSource);

            //le set handler devrait être sur le type destination

            if (_Converter != null)
            {
                _CurrentChanged = OnValueChanged1;
                sethandlerDest  = GetSetUtils.CreateSetHandler <TValueDest>(piDest);
            }
            else
            {
                _CurrentChanged = OnValueChanged;
                sethandler      = GetSetUtils.CreateSetHandler <TValueSource>(piDest);
            }

            DataBinder.AddNotify <TValueSource>(source, piSource.Name, gethandler, _CurrentChanged, applyBindingContext);
        }
        /// <summary>
        /// it for intermediate notifications, to rebind
        /// </summary>
        /// <param name="current">concerned object</param>
        /// <param name="pathitem">real property name</param>
        /// <param name="onchanged">delegate to call, when propertyname changed</param>
        private void AddNotify(object current, string pathitem, OnChangeDelegate <object> onchanged)
        {
            PropertyInfo pi = current.GetType().GetProperty(pathitem);

            GetHandlerDelegate <object> gethandler = GetSetUtils.CreateGetHandler <object>(pi);

            DataBinder.AddNotify <object>(current, pathitem, gethandler, onchanged, null);
        }
Beispiel #4
0
        /// <summary>
        /// créée une méthode dynamique, pour lire le contenu d'une propriété sans utiliser la réflection
        /// </summary>
        /// <typeparam name="TValue"></typeparam>
        /// <typeparam name="TInstance"></typeparam>
        /// <param name="propertyInfo"></param>
        /// <returns></returns>
        public static GetHandlerDelegate <TValue> CreateGetHandler <TValue>(PropertyInfo propertyInfo)
        {
            MethodInfo getMethod = propertyInfo.GetGetMethod(true);

            if (_Dico.ContainsKey(getMethod))
            {
                return((GetHandlerDelegate <TValue>)_Dico[getMethod]);
            }
#if SILVERLIGHT
            ////it's work, but at runtime a SecurityException is thrown
            //DynamicMethod dynamicGet = new DynamicMethod("DynamicGet" + propertyInfo.Name,
            //                                                typeof(TValue),
            //                                                new Type[] { typeof(object) });
            //it's not compiled, but it work
            GetHandlerDelegate <TValue> Result = delegate(object sender)
            {
                return((TValue)getMethod.Invoke(sender, null));
            };
            //ILGenerator getGenerator = dynamicGet.GetILGenerator();
            //getGenerator.Emit(OpCodes.Ldarg_0);
            //getGenerator.Emit(OpCodes.Callvirt, getMethod);
            //getGenerator.Emit(OpCodes.Ret);

            //Type tDelegate = typeof(GetHandlerDelegate<TValue>);
            //GetHandlerDelegate<TValue> Result = (GetHandlerDelegate<TValue>)dynamicGet.CreateDelegate(tDelegate);
#else
            DynamicMethod dynamicGet = new DynamicMethod("DynamicGet" + propertyInfo.Name,
                                                         typeof(TValue),
                                                         new Type[] { typeof(object) },
                                                         propertyInfo.DeclaringType, true);
            ILGenerator getGenerator = dynamicGet.GetILGenerator();
            getGenerator.Emit(OpCodes.Ldarg_0);
            getGenerator.Emit(OpCodes.Call, getMethod);
            getGenerator.Emit(OpCodes.Ret);

            Type tDelegate = typeof(GetHandlerDelegate <TValue>);
            GetHandlerDelegate <TValue> Result = (GetHandlerDelegate <TValue>)dynamicGet.CreateDelegate(tDelegate);
#endif
            _Dico[getMethod] = Result;
            return(Result);
        }
Beispiel #5
0
 public OneNotify(GetHandlerDelegate <T> getter, OnChangeDelegate <T> onchanged)
 {
     _OnGet     = getter;
     _OnChanged = onchanged;
 }
Beispiel #6
0
        /// <summary>
        /// gestion de la notification sur INotifyPropertyChanged
        /// </summary>
        /// <typeparam name="T">type de la propriété observée</typeparam>
        /// <param name="source">source</param>
        /// <param name="propName">property à observer</param>
        /// <param name="gethandler">"get" a appeler a chaque changements</param>
        /// <param name="OnValueChange">la déléguée à appelée après chaque changed de la source</param>
        internal static void AddNotify <T>(object source, string propName, GetHandlerDelegate <T> gethandler, OnChangeDelegate <T> OnValueChange, SynchronizationContext applyBindingContext)
        {
            INotifyPropertyChanged inotify = source as INotifyPropertyChanged;

            if (inotify != null)
            {
                EqualityWeakReference weak = new EqualityWeakReference(inotify);
                //le but est ici de ne s'abonner qu'une fois
                Dictionary <string, IOneNotify> dico = null;
                if (!_SourceChanged.TryGetValue(weak, out dico))
                {
                    dico = new Dictionary <string, IOneNotify>();
                    _SourceChanged.Add(weak, dico);
                    inotify.PropertyChanged += delegate(object sender, PropertyChangedEventArgs e)
                    {
                        //je minimise le nombre de get, en founissant la valeur qui à changé
                        if (dico.ContainsKey(e.PropertyName))
                        {
                            dico[e.PropertyName].Fire(weak);
                        }
                    };
                }
                ///plusieurs abonnement si nécessaire pour une propriété binding de 1 prop vers plusieurs dest
                OneNotify <T> binding = null;
                if (dico.ContainsKey(propName))
                {
                    binding            = (OneNotify <T>)dico[propName];
                    binding._OnChanged = (OnChangeDelegate <T>)Delegate.Combine(binding._OnChanged, OnValueChange);
                }
                else
                {
                    binding = new OneNotify <T>(gethandler, OnValueChange);
                    binding._ApplyBindingContext = applyBindingContext;
                    binding.PropertyName         = propName;
                    dico[propName] = binding;
                }
            }
            else if (source != null)
            {
                //try with old mode "PropertyName"Changed event
                string    eventName = string.Format("{0}Changed", propName);
                EventInfo evInfo    = source.GetType().GetEvent(eventName);
                if (evInfo != null)
                {
                    EqualityWeakReference weak = new EqualityWeakReference(source);
                    //le but est ici de ne s'abonner qu'une fois
                    Dictionary <string, IOneNotify> dico = null;
                    if (!_SourceChanged.TryGetValue(weak, out dico))
                    {
                        dico = new Dictionary <string, IOneNotify>();
                        _SourceChanged.Add(weak, dico);
                    }

                    ///plusieurs abonnement si nécessaire pour une propriété binding de 1 prop vers plusieurs dest
                    OneNotify <T> binding = null;
                    if (dico.ContainsKey(propName))
                    {
                        binding            = (OneNotify <T>)dico[propName];
                        binding._OnChanged = (OnChangeDelegate <T>)Delegate.Combine(binding._OnChanged, OnValueChange);
                    }
                    else
                    {
                        binding = new OneNotify <T>(gethandler, OnValueChange);
                        binding.PropertyName          = propName;
                        binding._ApplyBindingContext  = applyBindingContext;
                        binding._PropertyChangedEvent = delegate
                        {
                            binding.Fire(weak);
                        };
                        dico[propName] = binding;
                        evInfo.AddEventHandler(source, binding._PropertyChangedEvent);
                    }
                }
            }
        }