コード例 #1
0
        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);
        }
コード例 #2
0
        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}.");
        }
コード例 #3
0
ファイル: ObservableSource.cs プロジェクト: drminor/propbag
        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);
            }
            }
        }
コード例 #4
0
        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}.");
            }
        }
コード例 #5
0
        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);
        }
コード例 #6
0
        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);
        }
コード例 #7
0
        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);
        }