Palette, Diagram, Drag'n'Drop And PartManager

Hi,

I evaluating GoXam Silverlight (Version 1.0.1.3)

I have setup a diagram and a palette. I can drag n drop node from the palette to the diagram area, such as the flowchart example.

I’m trying to detect when i drag and drop a node from the palette to the diagram, get the dropped node and insert a record, concerning that node, into database.

I don’t really understand how the diagram PartManager and diagram event ExternalObjectsDropped can work together.

The event ExternalObjectsDropped give me almost nothing to work with, concerning the node, but i know that something was dropped.

On the PartManager OnNodeAdded(), i have the added node, but nothing about the fact that it come from drag and drop from the palette.

Did i miss something to be able to launch some code, when i drop a node on the diagram from the palette, and be able to know that it was a node wich was dropped ?

First, the simple answer to your question is that in your Diagram.ExternalObjectsDropped event handler you can look at the Diagram.SelectedParts collection to see what was dropped.

(The same is true for many of the other Diagram events that operate on the selection, such as Diagram.SelectionMoved or Diagram.ClipboardPasted.)

Second, the issue of when to update the underlying database is a bit more complicated. I assume you do not want the “Save/Load” paradigm of user-directed persistence, but that you do want to keep the database up-to-date “all the time”.

If that’s the case for your application, you probably only want to update your database when a diagram transaction completes. That way you can ignore any temporary node creations, such as when the user cancels the operation they were performing.

There are at least two implementation strategies to accomplish this. You can either implement a DiagramModel.Changed event handler, or you can customize the model’s UndoManager to override the UndoManager.CommitCompoundEdit method.

If you want to implement a DiagramModel.Changed event handler, either add an event handler or override its OnChanged method (and call the base method!). Its ModelChangedEventArgs.Change property will describe the kind of change that just occurred. Look for the ModelChange.CommitedTransaction value.

If you want to override the UndoManager.CommitCompoundEdit method, call the base method first. You also need to make sure you set your model’s DiagramModel.UndoManager property to refer to an instance of your custom undo manager class.

With either implementation strategy you’ll get an UndoManager.CompoundEdit that describes all of the model changes that have occurred within the model transaction. (It’s either the return value from calling the base method or it’s the ModelChangedEventArgs.OldValue.)

You can then iterate over all of the CompoundEdit.Edits and look for the change events that you care about, such as ModelChange.AddedNode and ModelChange.RemovedNode. The ModelChangedEventArgs.Data property will give you the node data.

I hope I have explained myself well enough. In particular, I hope it’s clear that a “mouse-up” or “dropped” event is probably not the right time to modify a database.

Thanks a lot ! Your reply really helps me to understand how those things work !

I went for the override of the OnModelChange() method in the PartManager.

If it can benefits to others, this is what i ended with :

Public Overrides Sub OnModelChanged(ByVal e As Northwoods.GoXam.Model.ModelChangedEventArgs)
        MyBase.OnModelChanged(e)

        If e.Change = Model.ModelChange.CommittedTransaction Then
            If e.Model.UndoManager.CurrentEdit IsNot Nothing Then
                For Each edit In e.Model.UndoManager.CurrentEdit.Edits
                    If TryCast(edit, Northwoods.GoXam.Model.ModelChangedEventArgs).Change = Model.ModelChange.AddedNode Then
                        Dim nodeData As MyNodeData = TryCast(e.Model.UndoManager.CurrentEdit.Edits.Item(0), Northwoods.GoXam.Model.ModelChangedEventArgs).Data

                        If nodeData.Category = "Standard" OrElse _
                           nodeData.Category = "Start" OrElse _
                           nodeData.Category = "End" Then
                            ApplicationSharedData.AddNodeToDatabase(nodeData)
                        End If
                    End If
                Next
            End If
            
        End If
    End Sub

Small mistake :

Public Overrides Sub OnModelChanged(ByVal e As Northwoods.GoXam.Model.ModelChangedEventArgs)
        MyBase.OnModelChanged(e)

        If e.Change = Model.ModelChange.CommittedTransaction Then
            If e.Model.UndoManager.CurrentEdit IsNot Nothing Then
                For Each edit In e.Model.UndoManager.CurrentEdit.Edits
                    If TryCast(edit, Northwoods.GoXam.Model.ModelChangedEventArgs).Change = Model.ModelChange.AddedNode Then
                        Dim nodeData As MyNodeData = TryCast(edit, Northwoods.GoXam.Model.ModelChangedEventArgs).Data

                        If nodeData.Category = "Standard" OrElse _
                           nodeData.Category = "Start" OrElse _
                           nodeData.Category = "End" Then
                            ApplicationSharedData.AddNodeToDatabase(nodeData)
                        End If
                    End If
                Next
            End If
            
        End If
    End Sub

I would add a declaration:
Dim edit as ModelChangedEventArgs
so that:
e.Model.UndoManager.CurrentEdit.Edits.Item(0)
could just be:
edit

[Edit: Never mind about the above suggestion; our posts crossed.]

I also suggest you import Northwoods.GoXam.Model, so that your code can be shorter and easier to read.

yes it should have been ‘edit’ instead of e.Model.UndoManager.CurrentEdit.Edits.Item(0).

I am new to GoXAML, so please excuse if my question is very basic. Where is Northwoods.GoXam.Model? Are there examples of how this is used?

Also if you could provide the link to the alpha / beta version that will be great.

Thanks

Northwoods.GoXam.Model is just a namespace for all of the model-related types used by every GoXam Diagram.

All GoXam types in all GoXam namespaces are contained in the single DLL, either Northwoods.GoSilverlight.dll or Northwoods.GoWPF.dll, depending on the platform.