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); }
public ObservableSource(IPropBag propBag, ExKeyT compKey, string pathElement, SourceKindEnum sourceKind, string binderName) { CompKey = compKey; PathElement = pathElement; BinderName = binderName; SourceKind = sourceKind; IDisposable disable = propBag.SubscribeToPropChanged(PropertyChangedWithGenVals_Handler, PathElement, typeof(T)); PropChangeGenUnsubscriber = disable ?? throw new InvalidOperationException($"Could not subscribe to EventHandler<PcGenEventArgs> PropertyChangedWithGenVals for {PathElement}."); }
private bool DoesDataHaveCorrectType(object data, SourceKindEnum sourceKind, out Type type) { if (data == null) { type = null; return(true); } switch (sourceKind) { case SourceKindEnum.DataGridColumn: { return(typeof(DependencyPropertyListener).IsAssignableFrom(type = data.GetType())); } case SourceKindEnum.DataSourceProvider: { return(typeof(DataSourceProvider).IsAssignableFrom(type = data.GetType())); } case SourceKindEnum.FrameworkContentElement: { return(typeof(FrameworkContentElement).IsAssignableFrom(type = data.GetType())); } case SourceKindEnum.FrameworkElement: { return(typeof(FrameworkElement).IsAssignableFrom(type = data.GetType())); } default: { // TODO: Check this. type = data.GetType(); return(true); } } }
public ObservableSource(INotifyParentNodeChanged notifyParentChangedSource, ExKeyT compKey, string pathElement, SourceKindEnum sourceKind, string binderName) { CompKey = compKey; PathElement = pathElement; BinderName = binderName; SourceKind = sourceKind; IDisposable disable; if (sourceKind == SourceKindEnum.AbsRoot) { // TODO: Subscribe to RootNodeChanged instead. disable = notifyParentChangedSource.SubscribeToParentNodeHasChanged(ParentNodeHasChanged_Handler); ParentChangedSource = disable ?? throw new InvalidOperationException($"Could not subscribe to EventHandler<PSNodeParentChangedEventArgs> ParentNodeHasChanged for {PathElement}."); } else { disable = notifyParentChangedSource.SubscribeToParentNodeHasChanged(ParentNodeHasChanged_Handler); ParentChangedSource = disable ?? throw new InvalidOperationException($"Could not subscribe to EventHandler<PSNodeParentChangedEventArgs> ParentNodeHasChanged for {PathElement}."); } }
private ObservableSource <T> CreateAndListen(BagNode propStoreNode, string pathComp, SourceKindEnum sourceKind) { ObservableSource <T> result = new ObservableSource <T>(propStoreNode, propStoreNode.CompKey, pathComp, sourceKind, BINDER_NAME); result.ParentHasChanged += ParentHasChanged_Handler; return(result); }
private ObservableSource <T> CreateAndListen(IPropBag propBag, ExKeyT compKey, string pathComp, SourceKindEnum sourceKind) { ObservableSource <T> result; if (sourceKind == SourceKindEnum.Down) { result = new ObservableSource <T>((IPropBag)propBag, compKey, pathComp, sourceKind, BINDER_NAME); result.PropertyChangedWithVals += PropertyChangedWithVals_Handler; } else if (sourceKind == SourceKindEnum.TerminalNode) { result = new ObservableSource <T>((IPropBag)propBag, compKey, pathComp, BINDER_NAME); result.PropertyChangedWithTVals += PropertyChangedWithTVals_Handler; } else { throw new InvalidOperationException($"CreateAndListen when supplied a propBag can only process nodes of source kind = {nameof(SourceKindEnum.Down)} and {nameof(SourceKindEnum.TerminalNode)}."); } return(result); }
private bool GetChangedNode(BagNode ourNode, ObservableSource <T> signalingNode, bool pathIsAbsolute, string[] pathElements, out BagNode next, out int nPtr) { int startIndex = _pathListeners.IndexOf(signalingNode); if (startIndex == -1) { throw new InvalidOperationException($"Could not get pointer to path element while processing DataSourceChanged event for {BINDER_NAME}."); } if (pathIsAbsolute) { SourceKindEnum sourceKind = signalingNode.SourceKind; System.Diagnostics.Debug.Assert(sourceKind == SourceKindEnum.Down || sourceKind == SourceKindEnum.TerminalNode, $"When the source path is absolute, GetChangedNode can only be called for a node whose kind is {nameof(SourceKindEnum.Down)} or {nameof(SourceKindEnum.TerminalNode)}."); next = ourNode.Root; if (next == null) { if (sourceKind == SourceKindEnum.Down) { System.Diagnostics.Debug.WriteLine("OurNode's root is null when processing DataSource Changed for 'intervening' node."); } else { System.Diagnostics.Debug.WriteLine("OurNode's root is null when processing Terminal node."); } nPtr = 0; return(false); } } else { next = ourNode; } // For terminal nodes: // Initially startIndex should point to the last path element. // On exit, next be the PropBag that owns the binding source propItem // and nPtr should point to the last listener. // For intervening nodes: // Initially startIndex should point to the element that was changed. // On exit, next should be the PropBag that owns the propItem of the property that was changed // and nPtr should point to the listener that changed. for (nPtr = 0; next != null && nPtr < startIndex; nPtr++) { string pathComp = pathElements[nPtr]; if (pathComp == "..") { next = next.Parent?.Parent; } else { if (TryGetPropBag(next, out IPropBag propBag)) { if (TryGetChildProp(next, /*propBag,*/ pathComp, out PropNode child)) { if (nPtr + 1 == pathElements.Length - 1) { // next is set to the node we wan't and we can access the child. } else { // Get the PropBag being hosted by this current object's property. 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; } } } return(next != null); }