Between ClickCreatingTool and DraggingTool

Hello again,

I’m using GoXam 1.3.2 for Silverlight and have done minor customizations of both of these tools. However, neither customization does what I’d like to do for inserting.
I want to be able to go into an insertion mode for a particular type of node. Then, as long as I’m in that insertion mode, I can attempt to insert such nodes into the diagram until I either change the type of node to insert or choose to move into an non-insert mode altogether.
The ClickCreatingTool doesn’t appear to be appropriate because
a) there must be visual cues to the user concerning where the insertion is valid as the user hovers over existing diagram parts; and
b) the user should see a representation of the node being inserted.
On the other hand, although DraggingTool does a) and b), there doesn’t appear to be a way to use it modally; I must select the node type from a palette and drag it to be able to insert. Although it’d be nice to stay in an insertion mode after insertion, it’s more important that a menu click can initiate insertion mode.
Is there something simple I’m missing? If not, what direction would be best to pursue?
I’ve gotten nowhere with overrides to the DraggingTool; would it be fruitful to try to make it modal via event handling?
Should I try to tweak the ClickCreatingTool to have visual cues?
Should I try to derive my own tool from DiagramTool? If so, any pointers?
Thanks, Jeff

[code] public class ModalClickCreatingTool : ClickCreatingTool {
private Node TemporaryNode { get; set; }

public override void DoStart() {
  base.DoStart();
  var temp = new Node();
  var cp = new ContentPresenter();
  cp.ContentTemplate = Diagram.FindResource<DataTemplate>(this.Diagram, "NodeTemplate4");
  cp.Content = new PartManager.PartBinding(temp, this.PrototypeData);
  temp.Content = cp;
  temp.LayerName = "Tool";
  temp.Location = this.Diagram.LastMousePointInModel;
  this.TemporaryNode = temp;
  this.Diagram.PartsModel.AddNode(temp);
}

public override void DoStop() {
  if (this.TemporaryNode != null) {
    this.Diagram.PartsModel.RemoveNode(this.TemporaryNode);
  }
  base.DoStop();
}

public override void DoMouseMove() {
  if (this.TemporaryNode != null) {
    this.TemporaryNode.Location = this.Diagram.LastMousePointInModel;
  }
}

public override void DoMouseUp() {
  if (this.Active) {
    InsertNode(this.Diagram.LastMousePointInModel);
  }
}

}[/code]
Of course you’ll want to substitute “NodeTemplate4” with the name of the actual node DataTemplate that you would normally use.

Have the command that goes into this mode do something like:
myDiagram.CurrentTool = new ModalClickCreatingTool() {
PrototypeData = new TestData() { . . . }
};

The user can get out of the mode by hitting ESCAPE, or by executing a command that replaces the Diagram.CurrentTool.

This looks good. Showing me an appropriate way to override DoStart is what I really needed .
Thank you, Walter

I’ve got a problem with this solution that has cropped up.
Suppose the user started the modal click creating tool but then decides to cancel out of the insertion prior to doing any inserting.
In such a case, pressing ESCAPE doesn’t work.
To stop the tool, the user needs to press ESC and then do a mouse click.

I wrote an event handler on the diagram's Panel so that a right mouse click can also stop the tool but I'd really like to get ESC to work.

That’s right – it should be the responsibility of the tool.

It works fine, but I guess your command changed keyboard focus away from the diagram.

You could add:
this.Diagram.Focus();
to the DoStart method.


That was the problem. The diagram is only a portion of the app and this command originates from elsewhere.

Thanks.