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); }
/// <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); } }