/// <summary> /// Event handler that is called when the watched node or a parent node below has disposed or its name changed. We then try to resolve the path again. /// </summary> /// <param name="sender"></param> /// <param name="source">Source of the tunneled event.</param> /// <param name="e"></param> private void EhWatchedNode_TunneledEvent(object sender, object source, Main.TunnelingEventArgs e) { if (IsDisposeInProgress) { return; } if (!(InternalDocumentNode == null)) { throw new InvalidProgramException(); } var senderAsDocNode = sender as IDocumentLeafNode; var sourceAsDocNode = source as IDocumentLeafNode; if (!(senderAsDocNode != null)) { throw new InvalidProgramException(); } if (!(sourceAsDocNode != null)) { throw new InvalidProgramException(); } if (e is DocumentPathChangedEventArgs) // here, we activly change our stored path, if the watched node or a parent has changed its name { var watchedPath = AbsoluteDocumentPath.GetAbsolutePath(senderAsDocNode); watchedPath = watchedPath.Append(_docNodePath.SubPath(watchedPath.Count, _docNodePath.Count - watchedPath.Count)); var oldPath = _docNodePath; _docNodePath = watchedPath; #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("DocNodeProxy.EhWatchedNode_TunneledEvent: Modified path, oldpath={0}, newpath={1}", oldPath, _docNodePath); #endif } // then we try to resolve the path again if ((e is DisposeEventArgs) || (e is DocumentPathChangedEventArgs)) { #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("DocNodeProxy.EhWatchedNode_TunneledEvent"); #endif var node = AbsoluteDocumentPath.GetNodeOrLeastResolveableNode(_docNodePath, sourceAsDocNode, out var wasResolvedCompletely); if (null == node) { throw new InvalidProgramException(nameof(node) + " should always be != null, since we use absolute paths, and at least an AltaxoDocument should be resolved here."); } if (wasResolvedCompletely) { ClearWatch(); SetDocNode(node); } else // not completely resolved { if (!object.ReferenceEquals(sender, node)) { ClearWatch(); SetWatchOnNode(node); } } } }
/// <summary> /// Sets the watch on a node that is not our document node, but a node lower in the hierarchy. We watch both the Changed event and the TunneledEvent of this node. /// </summary> /// <param name="node">The node to watch.</param> protected virtual void SetWatchOnNode(IDocumentLeafNode node) { if (null == node) { throw new ArgumentNullException(nameof(node)); } if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } node.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler <object, object, TunnelingEventArgs>(EhWatchedNode_TunneledEvent, handler => node.TunneledEvent -= handler)); node.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhWatchedNode_Changed, handler => node.Changed -= handler)); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("Start watching node <<{0}>> of total path <<{1}>>", AbsoluteDocumentPath.GetAbsolutePath(node), _docNodePath); #endif }
/// <summary> /// Sets the watch on a node that is not our document node, but a node lower in the hierarchy. We watch both the Changed event and the TunneledEvent of this node. /// </summary> /// <param name="node">The node to watch.</param> protected virtual void SetWatchOnNode(IDocumentLeafNode node) { #if DOCNODEPROXY_CONCURRENTDEBUG int debugUsn = System.Threading.Interlocked.Increment(ref _debugUSN); _debug.Enqueue("START SetWatchOnNode " + debugUsn.ToString()); #endif if (null == node) { throw new ArgumentNullException(nameof(node)); } if (null != _weakDocNodeChangedHandler) { _weakDocNodeChangedHandler.Remove(); _weakDocNodeChangedHandler = null; } if (null != _weakDocNodeTunneledEventHandler) { _weakDocNodeTunneledEventHandler.Remove(); _weakDocNodeTunneledEventHandler = null; } node.TunneledEvent += (_weakDocNodeTunneledEventHandler = new WeakActionHandler <object, object, TunnelingEventArgs>(EhWatchedNode_TunneledEvent, handler => node.TunneledEvent -= handler)); node.Changed += (_weakDocNodeChangedHandler = new WeakEventHandler(EhWatchedNode_Changed, handler => node.Changed -= handler)); #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("Start watching node <<{0}>> of total path <<{1}>>", AbsoluteDocumentPath.GetAbsolutePath(node), _docNodePath); #endif #if DOCNODEPROXY_CONCURRENTDEBUG _debug.Enqueue("STOP SetWatchOnNode " + debugUsn.ToString() + (_docNodeRef == null).ToString()); #endif }