private object BindToArray(object source, int currentIndex, PathItem pathitem)
        {
            //in future use, it will be insterresting to keep arrayIndex as string (i.e dictionary)
            int intArrayIndex = pathitem.ArrayIndex;

            EqualityWeakReference weakSource;

#if !SILVERLIGHT
            //Here source is a list, bindinglist, ... or has simply indexer
            if (source is IBindingList)
            {
                BindingListNotificationWrapper wrapper = new BindingListNotificationWrapper((IBindingList)source);
                wrapper.SetIndex(intArrayIndex);
                weakSource = new EqualityWeakReference(source);
                wrapper.CollectionChanged += delegate(object sender, CollectionChangedEventArgs e)
                {
                    if (weakSource.IsAlive)
                    {
                        UnBindReBindListItem(currentIndex, intArrayIndex, weakSource.Target);
                    }
                };
                IList l = ((IList)source);
                if (l.Count > intArrayIndex)
                {
                    source = l[intArrayIndex];
                }
                else
                {
                    source = null;
                }
                pathitem.ArrayWrapper = wrapper;
            }
            else
#endif
            if (source is ICollectionChanged)
            {
                weakSource = new EqualityWeakReference(source);
                ((ICollectionChanged)source).CollectionChanged += delegate(object sender, CollectionChangedEventArgs e)
                {
                    if (weakSource.IsAlive)
                    {
                        if (e.Action == CollectionChangedAction.Reset || e.NewIndex == intArrayIndex || e.OldIndex == intArrayIndex)
                        {
                            UnBindReBindListItem(currentIndex, intArrayIndex, weakSource.Target);
                        }
                    }
                };
                if (((IList)source).Count > intArrayIndex)
                {
                    source = ((IList)source)[intArrayIndex];
                }
                else
                {
                    source = null;
                }
            }
            else
            {
                IList l = source as IList;
                if (l != null)
                {
                    source = ((IList)source)[intArrayIndex];
                }
                else
                {
                    source = null;
                }
            }
            return(source);
        }
示例#2
0
        /// <summary>
        /// Recreate the link between final source property and final destination property
        /// </summary>
        private void RecreateRealBinding()
        {
            if (_CurrentBinding != null)
            {
                _CurrentBinding.UnBind();
            }
            _CurrentBinding = null;

            PathItem destPathItem = _DestinationBinding.LastItem;

            //last item path (property to bind)
            if (destPathItem == null || destPathItem.Source == null)
            {
                return;
            }
            PathItem srcPathItem = _SourceBinding.LastItem;

            if (srcPathItem == null || srcPathItem.Source == null)
            {
                return;
            }

            srcPathItem.ArrayWrapper = null;

            object       source, destination;
            PropertyInfo piSource, piDestination;

            source      = srcPathItem.Source.Target;
            destination = destPathItem.Source.Target;
            bool arrayWrapperIsValid;

            //special case if it's an array
            if (srcPathItem.IsArray)
            {
                piSource = null;
                srcPathItem.ArrayWrapper = CreateArrayWrapper(srcPathItem, srcPathItem, out arrayWrapperIsValid, delegate()
                {
                    if (_CurrentBinding != null)
                    {
                        _CurrentBinding.ForceUpdate();
                    }
                    else
                    {
                        RecreateRealBinding();
                    }
                });
                if (srcPathItem.ArrayWrapper == null)
                {
                    return;
                }
                piSource = srcPathItem.ArrayWrapper.GetType().GetProperty("ArrayValue");
                source   = srcPathItem.ArrayWrapper;
                if (!arrayWrapperIsValid)
                {
                    return;
                }
            }
            else
            {
                piSource = source.GetType().GetProperty(srcPathItem.PropertyName);
            }

            if (destPathItem.IsArray)
            {
                piDestination             = null;
                destPathItem.ArrayWrapper = CreateArrayWrapper(srcPathItem, destPathItem, out arrayWrapperIsValid, null);
                if (destPathItem.ArrayWrapper == null)
                {
                    return;
                }
                piDestination = destPathItem.ArrayWrapper.GetType().GetProperty("ArrayValue");
                destination   = destPathItem.ArrayWrapper;
            }
            else
            {
                piDestination = destination.GetType().GetProperty(destPathItem.PropertyName);
            }


            Type t = typeof(RealBinding <,>);
            Type realBindingType = t.MakeGenericType(piSource.PropertyType, piDestination.PropertyType);

            _CurrentBinding = (IRealBinding)Activator.CreateInstance(realBindingType);
            _CurrentBinding.Bind(source, piSource, destination, piDestination, _Converter, _ApplyBindingContext);
            _CurrentBinding.ForceUpdate();
        }
        public void BindPropertyPath(object source, int index)
        {
            if (source == null)
            {
                return;
            }
            PathItem pathitem = _Items[index];
            bool     isArray  = pathitem.IsArray;

            PropertyInfo pi = source.GetType().GetProperty(pathitem.PropertyName);

            if (pi == null)
            {
                CheckPropertyInfo(true, _PropertyPath, pathitem.PropertyName, source.GetType());
            }
            if (index == _Items.Count - 1)
            {
                pathitem.Source = new EqualityWeakReference(source);
                if (_OnfinalBind != null)
                {
                    _OnfinalBind(index, pi, source);
                }
                pathitem.IsBind = true;
                if (pathitem.IsArray && _factory != null)
                {
                    OnChangeDelegate <object> onchanged = delegate(object value)
                    {
                        if (pathitem.Source.IsAlive)
                        {
                            object target = pathitem.Source.Target;
                            RemoveNotify(index);
                            BindPropertyPath(target, index);
                        }
                    };
                    pathitem.OnChanged = onchanged;
                    //Add notification on source changed
                    AddNotify(source, pathitem.PropertyName, onchanged);
                }
            }
            else
            {
                EqualityWeakReference weakSource = new EqualityWeakReference(source);
                int currentIndex = index + 1;

                OnChangeDelegate <object> onchanged = null;
                if (_factory != null)
                {
                    onchanged = _factory(currentIndex, weakSource);
                }
                pathitem.Source    = weakSource;
                pathitem.OnChanged = onchanged;
                pathitem.IsBind    = true;
                //Add notification on source changed
                AddNotify(source, pathitem.PropertyName, onchanged);
                source = pi.GetValue(source, null);
                if (isArray)
                {
                    source = BindToArray(source, currentIndex, pathitem);
                }
                BindPropertyPath(source, currentIndex);
            }
        }