Cancel the model change


I've a scenario where, a node is not allowed to be deleted based on certain conditions. I tried to implement it by using RollbackTransaction in the model changed event handler when the Change value is RemovingNode. It doesn't work as expected (i.e., the node is not prevented from being deleted). I also noted that before "RemovingNode" change there is LinkRemoved, ToKeyRemoved & FromKeyRemoved changes. These things are done in different transaction I think so. So, even if RollbackTransaction worked I would have lost the links.

There are other scenarios where I want to cancel the model change. For example, prevent addition of new node, removal of links etc., based on certain conditions. I looked for e.Cancel (where e is ModelChangedEventArgs), to cancel the model change, but, it isn’t there.

So, how do I prevent certain changes to the model based on the criteria?

Thanks, Sunil

That right – ModelChangedEventArgs is not a CancelEventArgs, so it doesn’t support that kind of cancellation.

In general it’s best to prevent something bad from happening, to avoid getting into an invalid state. That’s much preferable to trying to fix up some state to make it valid again.

Is there a reason you couldn’t just set or data-bind Part.Deletable to false?

Thanks Walter, that helped.

I used the Part.Deleteable attached property to disable deletion of a node by binding it to a boolean value. The only thing I’m having problem with is, avoiding the addition of node to the diagram.

I’ve two diagrams (each has its own palette) & their Node types are different & I’m using the GraphModel for diagram’s model. I want to prevent user from dragging the nodes from the wrong palette (this causes InvalidCastException being thrown).

So, I created my own custom dragging tool whose constructor takes the Palette as argument. When user drags the node, the DraggingTool.Source is checked to determine if the drag is from their palette’s DraggingTool. If it’s not I call DraggingTool.Source.DoCancel() function. Instead of cancelling the drag, I want to display not allowed mouse cursor. So that user can continue dragging on to the correct diagram. By calling the DoCancel, the user has to start the dragging of node from the palette again. Below is the code snippet to the custom tool:

public class CustomDraggingTool : DraggingTool
    private Palette _sourcePalette;

    public CustomDraggingTool(Palette sourcePalette)
        if (sourcePalette == null)
            throw new ArgumentNullException("Source palette cannot be null");

        _sourcePalette = sourcePalette;

    protected override void DragOver(Point pt, bool moving, bool copying)
        if (DraggingTool.Source != null && DraggingTool.Source != this 
        && DraggingTool.Source != _sourcePalette.DraggingTool)

        base.DragOver(pt, moving, copying);

How do I show the not allowed mouse cursor (the Cursors doesnt have any icon to indicate not allowed)? And, how do I prevent InvalidCastException being thrown when I don’t use DoCancel function?

Thanks Smile

I don’t know what’s exactly possible in that situation. You could try overriding Diagram.PartManager.CopyParts to return an empty ICopyDictionary if the parts being copied come from the “wrong” kind of Diagram or Model.