Esempio n. 1
0
        /// <summary>
        /// Event handler that is called when the document node has disposed or name changed. Because the path to the node can have changed too,
        /// the path is renewed in this case. The <see cref="OnChanged" /> method is called then for the proxy itself.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="source"></param>
        /// <param name="e"></param>
        private void EhDocNode_TunneledEvent(object sender, object source, Main.TunnelingEventArgs e)
        {
            if (IsDisposeInProgress)
            {
                return;
            }

#if DEBUG_DOCNODEPROXYLOGGING
            Current.Console.WriteLine("RelDocNodeProxy.EhDocNode_TunneledEvent: sender={0}, source={1} e={2}", sender, source, e);
#endif

            bool shouldFireChangedEvent = false;
            var  senderAsNode           = source as IDocumentLeafNode;
            if (!(senderAsNode != null))
            {
                throw new InvalidProgramException();
            }

            if (e is DisposeEventArgs)
            {
                // when our DocNode was disposed, it is probable that the parent of this node (and further parents) are disposed too
                // thus we need to watch the first node that is not disposed
                var docNode = InternalDocNode;
                ClearDocNode();

                if (!(sender is AltaxoDocument)) // if the whole document is disposed, there is no point in trying to watch something
                {
                    // note Dispose is designed to let the hierarchy from child to parent (root) valid, but not from root to child!
                    // thus trying to get an actual document path here is in must cases unsuccessfull. We have to rely on our stored path, and that it was always updated!
                    // the only case were it is successfull if a new node immediately replaces an old document node

                    var node = RelativeDocumentPath.GetNodeOrLeastResolveableNode(_docNodePath, senderAsNode, out var wasResolvedCompletely);
                    if (wasResolvedCompletely)
                    {
                        InternalSetDocNode(node, _parent);
                    }
                    else
                    {
                        SetWatchOnNode(node);
                    }

                    shouldFireChangedEvent = true;
                }
            }
            else if (e is DocumentPathChangedEventArgs)
            {
                if (null != InternalDocNode)
                {
                    InternalDocumentPath = RelativeDocumentPath.GetRelativePathFromTo(_parent, InternalDocNode);
                }

                shouldFireChangedEvent = true;
            }

            if (shouldFireChangedEvent)
            {
                EhSelfChanged(EventArgs.Empty);
            }
        }
Esempio n. 2
0
        /// <summary>
        /// Sets the document node that is held by this proxy.
        /// </summary>
        /// <param name="value">The document node. If <c>docNode</c> implements <see cref="Main.IDocumentLeafNode" />,
        /// the document path is stored for this object in addition to the object itself.</param>
        /// <param name="parentNode">The start point of the document path. Should be equal to the member _parent, but this might be not set now.</param>
        protected void InternalSetDocNode(Main.IDocumentLeafNode value, IDocumentLeafNode parentNode)
        {
            if (!IsValidDocument(value))
            {
                throw new ArgumentException("This type of document is not allowed for the proxy of type " + GetType().ToString());
            }
            if (null == parentNode)
            {
                throw new InvalidOperationException("Parent of this node must be set in order to set the docnode.");
            }

            var oldValue = InternalDocNode;

            if (object.ReferenceEquals(oldValue, value))
            {
                return; // Nothing to do
            }
            if (null != _weakDocNodeChangedHandler)
            {
                _weakDocNodeChangedHandler.Remove();
                _weakDocNodeChangedHandler = null;
            }
            if (null != _weakDocNodeTunneledEventHandler)
            {
                _weakDocNodeTunneledEventHandler.Remove();
                _weakDocNodeTunneledEventHandler = null;
            }

            if (null != oldValue)
            {
                ClearDocNode();
            }

            var newPath = RelativeDocumentPath.GetRelativePathFromTo(parentNode, value);

            if (null != newPath)
            {
                InternalDocumentPath = newPath; // especially in dispose situations, the new path can be null. In this case we leave the path as it was
            }
            _docNodeRef = new WeakReference(value);

#if DEBUG_DOCNODEPROXYLOGGING
            Current.Console.WriteLine("RelDocNodeProxy.SetDocNode, path is <<{0}>>", _docNodePath);
#endif

            value.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler <object, object, TunnelingEventArgs>(EhDocNode_TunneledEvent, handler => value.TunneledEvent -= handler));

            if (null != _docNodePath && !_docNodePath.IsIdentity) // it does not make sense to watch the changed event of our target node is our parent because the parent can handle the Changed event itself
            {
                value.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhDocNode_Changed, handler => value.Changed -= handler));
            }

            OnAfterSetDocNode();

            EhSelfChanged(new Main.InstanceChangedEventArgs(oldValue, value));
        }
Esempio n. 3
0
        public override void EhParentTunnelingEventHappened(IDocumentNode sender, IDocumentNode originalSource, TunnelingEventArgs e)
        {
            // since we deal with relative path, we have to watch changes to our path too
            if (e is Main.DocumentPathChangedEventArgs)
            {
                var node = InternalDocNode;
                if (null != node)
                {
                    _docNodePath = RelativeDocumentPath.GetRelativePathFromTo(_parent, node);
                }
            }

            base.EhParentTunnelingEventHappened(sender, originalSource, e);
        }
Esempio n. 4
0
        /// <summary>
        /// Event handler that is called when the document node has changed. Because the path to the node can have changed too,
        /// the path is renewed in this case. The <see cref="OnChanged" /> method is called then for the proxy itself.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void EhDocNode_Changed(object sender, EventArgs e)
        {
            if (IsDisposeInProgress)
            {
                return;
            }

#if DEBUG_DOCNODEPROXYLOGGING
            Current.Console.WriteLine("DocNodeProxy.EhDocNode_Changed: sender={0}, e={1}", sender, e);
#endif

            if (null != InternalDocNode)
            {
                _docNodePath = RelativeDocumentPath.GetRelativePathFromTo(_parent, InternalDocNode);
            }

            EhSelfChanged(EventArgs.Empty);
        }