private bool StartBinding(string[] pathElements, OSCollection <T> pathListeners, bool pathIsAbsolute, out PropNode sourcePropNode) { bool isComplete = false; BagNode next; if (pathIsAbsolute) { next = _ourNode.Root; if (next == null) { System.Diagnostics.Debug.WriteLine("OurNode's root is null when starting the local binding."); sourcePropNode = null; return(isComplete); } } else { next = _ourNode; } int nPtr = 0; isComplete = HandleNodeUpdate(next, pathElements, pathListeners, nPtr, out sourcePropNode); return(isComplete); }
// Base Constructor private LocalWatcher(PSAccessServiceInterface propStoreAccessService, LocalBindingInfo bindingInfo) { if (propStoreAccessService is PSAccessServiceInternalInterface propStoreAccessService_Internal) { _propStoreAccessService_wr = new WeakReference <PSAccessServiceInternalInterface>(propStoreAccessService_Internal); } else { throw new InvalidOperationException($"The propStoreAcccessService does not implement the internal interface: {nameof(PSAccessServiceInternalInterface)}."); } _ourNode = GetPropBagNode(propStoreAccessService); _bindingInfo = bindingInfo; _pathListeners = new OSCollection <T>(); BindingPathParser pathParser = new BindingPathParser(); _pathElements = pathParser.GetPathElements(bindingInfo, out _isPathAbsolute, out _firstNamedStepIndex); if (_isPathAbsolute) { _rootListener = CreateAndListen(_ourNode, "root", SourceKindEnum.AbsRoot); } else { _rootListener = null; } }
//Lazy<IValueConverter> _defaultConverter; //public virtual Lazy<IValueConverter> DefaultConverter //{ // get // { // if(_defaultConverter == null) // { // return new Lazy<IValueConverter>(() => new PropValueConverter()); // } // return _defaultConverter; // } // set // { // _defaultConverter = value; // } //} //Func<BindingTarget, MyBindingInfo, Type, string, object> _defConvParamBuilder; //public virtual Func<BindingTarget, MyBindingInfo, Type, string, object> DefaultConverterParameterBuilder //{ // get // { // if (_defConvParamBuilder == null) // { // return OurDefaultConverterParameterBuilder; // } // return _defConvParamBuilder; // } // set // { // _defConvParamBuilder = value; // } //} #endregion #region Constructor internal LocalBinder(PSAccessServiceInterface propStoreAccessService, LocalBindingInfo bindingInfo, IReceivePropStoreNodeUpdates storeNodeUpdateReceiver) { _propStoreAccessService_wr = new WeakReference <PSAccessServiceInterface>(propStoreAccessService); _bindingInfo = bindingInfo; _storeNodeUpdateReceiver = storeNodeUpdateReceiver; _bindingTarget = new SimpleExKey(); // Get the PropStore Node for the IPropBag object hosting the property that is the target of the binding. // TODO: Instead of doing this now, create a property that allows us to access upon first access. _ourNode = GetPropBagNode(propStoreAccessService); _targetObject = null; _propertyName = null; _targetHasStore = PropStorageStrategyEnum.Virtual; _pathElements = GetPathElements(_bindingInfo, out _isPathAbsolute, out _firstNamedStepIndex); if (_isPathAbsolute) { _rootListener = CreateAndListen(_ourNode, "root", SourceKindEnum.AbsRoot); } else { _rootListener = null; } _pathListeners = new OSCollection <T>(); _isComplete = StartBinding(_targetObject, _pathElements, _pathListeners, _isPathAbsolute); }
public LocalBinder(PSAccessServiceInterface propStoreAccessService, ExKeyT ownerPropId, LocalBindingInfo bindingInfo) { _propStoreAccessService_wr = new WeakReference <PSAccessServiceInterface>(propStoreAccessService); _bindingTarget = ownerPropId; _bindingInfo = bindingInfo; _storeNodeUpdateReceiver = null; // Get the PropStore Node for the IPropBag object hosting the property that is the target of the binding. _ourNode = GetPropBagNode(propStoreAccessService); PropIdType propId = _bindingTarget.Level2Key; _targetObject = _ourNode.PropBagProxy; if (_targetObject.TryGetTarget(out IPropBagInternal propBag)) { _propertyName = GetPropertyName(propStoreAccessService, propBag, propId, out PropStorageStrategyEnum storageStrategy); _targetHasStore = storageStrategy; } _pathElements = GetPathElements(_bindingInfo, out _isPathAbsolute, out _firstNamedStepIndex); if (_isPathAbsolute) { _rootListener = CreateAndListen(_ourNode, "root", SourceKindEnum.AbsRoot); } else { _rootListener = null; } _pathListeners = new OSCollection <T>(); _isComplete = StartBinding(_targetObject, _pathElements, _pathListeners, _isPathAbsolute); }
private bool AddOrUpdateListener(BagNode propStoreNode, string pathComp, SourceKindEnum sourceKind, OSCollection <T> pathListeners, int nPtr) { bool result; if (pathListeners.Count > nPtr) { ObservableSource <T> listener = pathListeners[nPtr]; if (propStoreNode.CompKey != listener.CompKey || sourceKind != listener.SourceKind) { listener.Dispose(); ObservableSource <T> newListener = CreateAndListen(propStoreNode, pathComp, sourceKind); pathListeners[nPtr] = newListener; result = true; } else { result = false; } } else { ObservableSource <T> newListener = CreateAndListen(propStoreNode, pathComp, sourceKind); pathListeners.Add(newListener); result = true; } return(result); }
private bool HandleNodeUpdate(BagNode next, string[] pathElements, OSCollection <T> pathListeners, int nPtr, out PropNode sourcePropNode) { bool complete = false; sourcePropNode = null; // Process each step, except for the last. for (; next != null && nPtr < pathElements.Length - 1; nPtr++) { string pathComp = pathElements[nPtr]; if (pathComp == "..") { bool listenerWasAdded = AddOrUpdateListener(next, pathComp, SourceKindEnum.Up, pathListeners, nPtr); string mg = listenerWasAdded ? "added" : "updated"; System.Diagnostics.Debug.WriteLine($"The Listener for step: {pathComp} was {mg}."); next = next.Parent?.Parent; } else { if (TryGetPropBag(next, out IPropBag propBag)) { bool listenerWasAdded = AddOrUpdateListener(propBag, next.CompKey, pathComp, SourceKindEnum.Down, pathListeners, nPtr); string mg = listenerWasAdded ? "added" : "updated"; System.Diagnostics.Debug.WriteLine($"The Listener for step: {pathComp} was {mg}."); if (TryGetChildProp(next, /*propBag, */ pathComp, out PropNode child)) { next = child.Child; } else { System.Diagnostics.Debug.WriteLine("Could not get reference to the PropItem's PropStoreNode during binding update."); next = null; } } else { System.Diagnostics.Debug.WriteLine("The weak reference to the PropBag refers to a ProBag which 'is no longer with us.'"); next = null; } } } // Add the terminal node. if (next != null) { System.Diagnostics.Debug.Assert(nPtr == pathElements.Length - 1, $"The counter variable: nPtr should be {pathElements.Length - 1}, but is {nPtr} instead."); if (TryGetPropBag(next, out IPropBag propBag)) { string pathComp = pathElements[nPtr]; bool listenerWasAdded = AddOrUpdateListener(propBag, next.CompKey, pathComp, SourceKindEnum.TerminalNode, pathListeners, nPtr); string mg = listenerWasAdded ? "added" : "updated"; System.Diagnostics.Debug.WriteLine($"The Listener for terminal step: {pathComp} was {mg}."); // We have created or updated the listener for this step, advance the pointer. nPtr++; // We have subscribed to the property that is the source of the binding. complete = true; // Let's try to get the value of the property for which we just started listening to changes. if (TryGetChildProp(next, /*propBag,*/ pathComp, out sourcePropNode)) { if (NotifyReceiverWithStartingValue(sourcePropNode)) { System.Diagnostics.Debug.WriteLine($"The receiver has been notified during refresh. " + $"Source: {((IPropBag)propBag).FullClassName}, {pathComp}"); } else { System.Diagnostics.Debug.WriteLine("The binding source has been reached, but the receiver was not notified during refresh. " + $"Source: {((IPropBag)propBag).FullClassName}, {pathComp}"); } } else { System.Diagnostics.Debug.WriteLine("Could not get reference to the PropItem's PropStoreNode during binding update."); } } else { System.Diagnostics.Debug.WriteLine("The weak reference to the PropBag refers to a ProBag which 'is no longer with us.'"); } } for (; nPtr < pathListeners.Count; nPtr++) { ObservableSource <T> listener = pathListeners[nPtr]; listener.Dispose(); pathListeners.RemoveAt(nPtr); } return(complete); }
private bool StartBinding(WeakReference <IPropBagInternal> bindingTarget, string[] pathElements, OSCollection <T> pathListeners, bool pathIsAbsolute) { StoreNodeBag next; if (pathIsAbsolute) { next = _ourNode.Root; if (next == null) { System.Diagnostics.Debug.WriteLine("OurNode's root is null when starting the local binding."); return(false); } } else { next = _ourNode; } int nPtr = 0; bool complete = HandleNodeUpdate(bindingTarget, next, pathElements, pathListeners, nPtr); return(complete); }