/// <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); } }
/// <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 (!(_docNodeRef == 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(); } // 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 = RelativeDocumentPath.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(); InternalSetDocNode(node, _parent); } else // not completely resolved { if (!object.ReferenceEquals(sender, node)) { ClearWatch(); SetWatchOnNode(node); } } } }
/// <summary> /// Event handler that is called when the watched node (a node that is not the document node) has changed. Maybe this watched node had now created a parent node, and our /// document path can resolved now. That's why we try to resolve our document path now. /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void EhWatchedNode_Changed(object sender, EventArgs e) { if (IsDisposeInProgress) { return; } #if DEBUG_DOCNODEPROXYLOGGING Current.Console.WriteLine("DocNodeProxy.EhWatchedNode_Changed: sender={0}, e={1}", sender, e); #endif if (!(_docNodeRef == null)) { throw new InvalidProgramException(); } var senderAsDocNode = sender as IDocumentLeafNode; if (!(senderAsDocNode != null)) { throw new InvalidProgramException(); } var node = RelativeDocumentPath.GetNodeOrLeastResolveableNode(_docNodePath, senderAsDocNode, out var wasResolvedCompletely); if (null == node) { throw new InvalidProgramException("node should always be != null, since we use absolute paths, and at least an AltaxoDocument should be resolved here."); } if (wasResolvedCompletely) { ClearWatch(); InternalSetDocNode(node, _parent); } else // not completely resolved { if (!object.ReferenceEquals(sender, node)) { ClearWatch(); SetWatchOnNode(node); } } }