Overview component questions


We’re using goXam in our application (WPF,, and I’m trying to get the Overview component to have the same behavior as the GoOverview control, namely the selectable/draggable zoom (creating the Bounding Box by holding and dragging the left mouse button).

Not sure how to do this. I guess I have to either implement a custom DragSelectingTool or DragZoomingTool (or both), but I was wondering if there was an easier way to do this.



I think this shouldn’t be too hard to implement. I’ll take a look when I get a chance.

I haven’t tried this in 1.0.*, but I have tried this in 1.1.7.

First, let’s customize the Overview.Box, mostly to specify a Cursor:

<go:Overview x:Name="myOverview" . . .> <go:Overview.BoxTemplate> <DataTemplate> <Rectangle Stroke="Blue" StrokeThickness="12" Fill="Transparent" go:Part.LayerName="Tool" Cursor="SizeAll" /> </DataTemplate> </go:Overview.BoxTemplate> </go:Overview>
We’ll replace the standard Overview tool that handles mouse down/move/up (it’s internal – not public). And we’ll make use of a DragZoomingTool.

Instead of having two separate tools, we’ll just define one that acts either like the one that scrolls the Overview.Observed diagram or that acts like a regular DragZoomingTool. The StartedOverBox property is set when the tool activates; the property controls whether the tool acts like a DragZoomingTool or not.

[code] public class CustomDragZoomingTool : DragZoomingTool {
public override bool CanStart() {
if (!this.MouseEnabled) return false;
if (this.Diagram == null || !(this.Diagram is Overview)) return false;
if (!IsLeftButtonDown()) return false;
return true;

public override void DoActivate() {
  Overview ov = this.Diagram as Overview;
  if (ov == null) return;
  Node node = ov.Panel.FindElementAt<Node>(ov.LastMousePointInModel, x => Part.FindAncestor<Node>(x as Visual),
          x => true, SearchLayers.Temporary | SearchLayers.Nodes);
  this.StartedOverBox = (node != null && node.Layer.IsTemporary);
  if (this.StartedOverBox) {
    Point last = ov.LastMousePointInModel;
    Point boxpos = node.Position;
    this.Offset = new Point(last.X-boxpos.X, last.Y-boxpos.Y);

private bool StartedOverBox { get; set; }
private Point Offset { get; set; }

public override void DoMouseMove() {
  if (!this.Active) return;
  if (this.StartedOverBox) {
  } else {

public override void DoMouseUp() {
  if (!this.Active) return;
  if (this.StartedOverBox || !IsBeyondDragSize()) {
  } else {

private void ScrollObserved() {
  Overview ov = this.Diagram as Overview;
  if (ov != null && ov.Observed != null) {
    Diagram obdiag = ov.Observed;
    DiagramPanel obpanel = obdiag.Panel;
    if (obpanel != null) {
      Rect viewport = obpanel.ViewportBounds;
      Point pt = ov.LastMousePointInModel;
      obpanel.Position = new Point(pt.X-this.Offset.X, pt.Y-this.Offset.Y);

public override void ZoomToRect(Rect brect) {
  Diagram observed = this.ZoomedDiagram;
  if (observed == null) observed = this.Diagram;
  if (observed == null || this.Diagram == null) return;

  double vrectw = observed.Panel.ViewportWidth;
  // do scale first, so DiagramPanel.NormalizePosition isn't constrained unduly when increasing scale
  observed.Panel.Scale = Math.Min(vrectw/brect.Width, 4);
  observed.Panel.Position = new Point(brect.X, brect.Y);

Finally, here’s how we’ll set it up: by removing the standard Overview tool and installing our custom one. Just for simplicity we’ll remove all of the standard mouse tools.

[code] // setup the Overview control later, when both controls have been initialized
this.Loaded += (s, e) => {
myOverview.DragZoomingTool = new CustomDragZoomingTool();
myOverview.DragZoomingTool.ZoomedDiagram = myDiagram;

    myOverview.Observed = myDiagram;

Thank you very much, Walter.

I’m trying this right now.