[code] public class RoutingLinkTool : DiagramTool {
public override void DoActivate() {
base.DoActivate();
StartTransaction("New Routed Link");
CaptureMouse();
#if SILVERLIGHT
this.Diagram.Cursor = Cursors.Stylus;
#else
this.Diagram.Cursor = Cursors.Cross;
#endif
}
public override void DoDeactivate() {
base.DoDeactivate();
this.Diagram.Cursor = null;
ReleaseMouse();
StopTransaction();
this.CurrentData = null;
this.CurrentLink = null;
}
MyLinkData CurrentData { get; set; }
Link CurrentLink { get; set; }
String IntendedLayerName { get; set; }
private void AddPoint(Point p) {
// make sure there's a new MyLinkData in the model
MyLinkData d = this.CurrentData;
if (d == null) {
// create and initialize the MyLinkData
d = new MyLinkData();
d.Points = new List<Point>();
this.CurrentData = d;
// add the MyLinkData to the model to produce a Link
((MyModel)this.Diagram.Model).AddLink(d);
this.CurrentLink = this.Diagram.PartManager.FindLinkForData(d, this.Diagram.Model);
// temporarily put into the temporary "Tool" layer, so it's in front of anything else
this.IntendedLayerName = this.CurrentLink.LayerName;
this.CurrentLink.LayerName = "Tool";
}
// add the Point to the data and to the PointCollection
var pts = d.Points.ToList();
pts.Add(p);
d.Points = pts;
this.CurrentLink.Route.Points = pts;
}
private void MoveLastPoint(Point p) {
MyLinkData d = this.CurrentData;
if (d == null) return;
if (((List<Point>)d.Points).Count > 0) {
// replace the last point in the data and in the PointCollection
((List<Point>)d.Points)[((List<Point>)d.Points).Count-1] = p;
}
}
private void RemoveLastPoint() {
MyLinkData d = this.CurrentData;
if (d == null) return;
if (((List<Point>)d.Points).Count > 0) {
// replace the last point in the data and in the PointCollection
((List<Point>)d.Points).RemoveAt(((List<Point>)d.Points).Count-1);
}
}
private void FinishShape() {
MyLinkData d = this.CurrentData;
if (d == null) return;
// if there aren't enough points, discard it by cancelling
if (((List<Point>)d.Points).Count < 2) {
DoCancel();
} else {
// put into desired layer and update the diagram bounds
this.CurrentLink.LayerName = this.IntendedLayerName;
this.CurrentLink.Route.Points = (List<Point>)d.Points;
this.Diagram.Panel.UpdateDiagramBounds();
// select the new Link
this.CurrentLink.IsSelected = true;
// and tell the tool to commit the transaction
this.TransactionResult = "New Routed Link";
StopTool();
}
}
public override void DoMouseDown() {
if (!this.Active) {
DoActivate();
// the first point
AddPoint(this.Diagram.LastMousePointInModel);
}
if (IsLeftButtonDown()) {
// a temporary end point to be replaced by DoMouseMove
AddPoint(this.Diagram.LastMousePointInModel);
} else { // e.g. right mouse down
FinishShape();
}
}
public override void DoMouseMove() {
if (this.Active) {
// the temporary last point follows the mouse
MoveLastPoint(this.Diagram.LastMousePointInModel);
}
}
public override void DoMouseUp() {
// don't stop this tool (the default behavior is to call StopTool)
}
public override void DoKeyDown(KeyEventArgs e) {
if (e.Key == Key.Enter) { // accept
// remove the temporary point, which is last
RemoveLastPoint();
FinishShape();
} else if (e.Key == Key.Z) { // undo
// remove a point, and treat the last one as a temporary one
RemoveLastPoint();
MoveLastPoint(this.Diagram.LastMousePointInModel);
} else {
base.DoKeyDown(e);
}
}
public override void DoCancel() {
if (this.CurrentData != null) {
((MyModel)this.Diagram.Model).RemoveLink(this.CurrentData);
}
base.DoCancel();
}
}[/code]
Use this as a modal tool by setting Diagram.CurrentTool, such as:
myDiagram.CurrentTool = new RoutingLinkTool() { Diagram = myDiagram };
This was actually adapted from the PolylineDrawingTool that I provided in this forum, http://www.nwoods.com/forum/forum_posts.asp?TID=3485.
If you want to draw orthogonal routes, you’ll need to adapt this code to automatically put in extra points to ensure that the route is orthogonal.