Trouble with Layers


I am a newbie. I have two problems. (1) How to capture the event generated when a Label is changed, (2) How to implement Layers when a new View is opened
I am writing an application based on the ProtoApp sample. However. my application requires two additional pieces of functionality.

  1. I need to update (add a new node) to the palette with the icons when a new node is created. A new node is created by dragging an existing node onto the drawing area. When the label is changed, I want to insert a new node with the new label as a new node in the palette window such that it is now a reusable node. I am thinking that I need to capture the changed_label event to fire off this event. (help)
  2. I need to open a new document window when an item on the drawing area is double-clicked. i.e. When I double click one of the nodes I place on the drawing area, I want to open a new MDI window where I can draw additional nodes that belong to this particular node. I am thinking that the best way to do this is to implement a new layer. [i.e. When item is double clicked-> get Item’s unique PartID, use-> generate a new layer and add it to the existing Document(GraphDoc) -> set the Layer identifier to the partID of the doubleclicked item, -> Open a new Window(GraphViewWindow) with the new layer as the layer for the window. That way, any items I place in the new window, belong to the same document, but a different layer.
    NB: I need to only show items on that particular layer. I don’t want items from other layers to show, although they belong to the same document.

(1) Well, there are a lot of possibilities, depending on when and why you want to get the event. Here's part of an entry from the FAQ: I'd like to know when someone changes the label of a node, so that I can update other data structures. Add a GoView.ObjectEdited event handler (or equivalently, override GoView.OnObjectEdited). You’ll need to check that the object that got edited, available through GoSelectionEventArgs.GoObject, is one you care about observing. If you want to be called when changes are made programmatically, you can add a GoDocument.Changed event handler (or equivalently, override GoDocument.OnChanged or GoView.OnDocumentChanged) to look for the GoLayer.ChangedObject hint with the GoText.ChangedText subhint. Again, you’ll need to make sure the modified GoText object is actually a label you care to keep track of rather than some other GoText object. (2) Using the node's PartID as the GoLayer.Identifier sounds like a reasonable approach. Here's a relevant question from the FAQ: Is it possible to have two views of the same diagram? This is easy to do because of the model-view-controller architecture that Go implements. If you just want a second window on the same document, create a second GoView, using the original GoDocument as the argument to the constructor. Or just set the GoView.Document property for another existing GoView. You can change the properties of this second view so that the user cannot do certain actions. You can even change the set of document layers or the order of the layers that are displayed in the view. For these latter possibilities, investigate the GoView.InitializeLayersFromDocument method and the GoLayerCollection methods InsertDocumentLayerBefore and InsertDocumentLayerAfter. You don't have to override InitializeLayersFromDocument, because you can manipulate the GoView.Layers collection explicitly, but it can be convenient to have the code in one place.


From your post in I’m wondering if my guidance for your second question wasn’t clear.
To repeat: set GoView.Document to the same document you are using everywhere, and call GoView.Layers.Clear() and then add the one layer you want to show in the view by calling GoView.Layers.InsertDocumentLayerBefore(null, aLayer). I think you already said you were able to find the desired layer by calling GoDocument.Layers.Find to find the layer with some identifier.
You might find it instructive to study what the ObjectBrowser sample displays. It actually generates a diagram showing the relevant internal data structures for two GoViews, a GoDocument, several GoLayers, two GoNodes, and a GoLink. Although both views are looking at the same document, one view’s layer collection has been modified by removing the document’s LinksLayer, so that view doesn’t show any links.


Thanks Walter,
Sorry for the confusion. What I was missing in my thought process was the GoView.Layers.Clear()


Off topic: Congratulations on contributing this forum’s one thousandth post!
On topic: Oops, I just checked the documentation, and there is no GoLayersCollection.Clear() method. If you do inherit from GoView, then you can override InitializeLayersFromDocument as follows:
public override void InitializeLayersFromDocument() {
if (this.Layers == null) return;
// clear out all view layers, remove all document layers
foreach (GoLayer layer in this.Layers.CopyArray()) {
if (layer.IsInView)
this.DocPosition = new PointF(); // reset to 0,0
// add the one document layer we care about
GoLayer aLayer = this.Document.Layers.Find(someIdentifier);
if (aLayer == null)
throw new Exception("couldn’t find layer: " + someIdentifier);
this.Layers.InsertDocumentLayerBefore(this.Layers.Default, aLayer);
This method will get called if you call the GoView constructor with a GoDocument argument, or when you set the GoView.Document property.
If you don’t inherit from GoView, you can just execute those statements after you set GoView.Document.


Phew, I noticed that GoLayersCollection.Clear() does not exist. Thought it might be because I am using GoExpress. I will try your suggestion.
The Sample Object Browser does not ship with GoExpress, is that correct?


I didn’t know you were using Express instead of Win. Yes, the ObjectBrowser sample doesn’t ship or work with GoDiagram Express. But all the layer manipulation code should work equally well in any version of GoDiagram, even Pocket. (Not that I had actually compiled any of the code I typed in this forum.)