AutoScroll when dragged outside viewport

Current Autoscroll works only inside the edge of the viewport.
We dont have any drag and drop operations in our diagram.
Can we make the diagram autoscroll even during drag out of window by overriding ComputeAutoScrollPosition and if yes how?

That’s an interesting question. I’ll see what can be done.

OK, I tried modifying the FamilyTree sample, which was convenient because it already has a lot of stuff in it. First, the custom DiagramPanel:

public class CustomDiagramPanel : DiagramPanel { // ignore DiagramPanel.AutoScrollRegion! protected override Point ComputeAutoScrollPosition(Point viewPnt) { var docpos = this.Position; // get the visible part of the panel Rect dispRect = new Rect(0, 0, this.ViewportWidth, this.ViewportHeight); // get the current panel position, in element coordinates Point viewpos = new Point(0, 0); if (viewPnt.X < dispRect.Left) { int deltaX = Math.Max((int)this.ScrollHorizontalLineChange, 1); viewpos.X -= deltaX*4; } else if (viewPnt.X > dispRect.Right) { int deltaX = Math.Max((int)this.ScrollHorizontalLineChange, 1); viewpos.X += deltaX*4; } if (viewPnt.Y < dispRect.Top) { int deltaY = Math.Max((int)this.ScrollVerticalLineChange, 1); viewpos.Y -= deltaY*4; } else if (viewPnt.Y > dispRect.Bottom) { int deltaY = Math.Max((int)this.ScrollVerticalLineChange, 1); viewpos.Y += deltaY*4; } // don't bother changing DOCPOS if VIEWPOS hasn't changed // Also avoids differences due to round-off errors! if (Math.Abs(viewpos.X) > 0.5 || Math.Abs(viewpos.Y) > 0.5) { // but return a Point in model coordinates double scale = this.Scale; docpos = new Point(docpos.X + viewpos.X/scale, docpos.Y + viewpos.Y/scale); } return docpos; } }
And the use of this DiagramPanel requires customizing the Diagram’s ControlTemplate:

<go:Diagram x:Name="myDiagram" Padding="10" HorizontalContentAlignment="Center" VerticalContentAlignment="Center" NodeTemplate="{StaticResource NodeTemplate}" LinkTemplateDictionary="{StaticResource LinkTemplateDictionary}"> <!-- custom DiagramPanel --> <go:Diagram.Template> <ControlTemplate TargetType="go:Diagram"> <Border x:Name="Border" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <ScrollViewer HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" CanContentScroll="True"> <local:CustomDiagramPanel x:Name="Panel" Stretch="{TemplateBinding Stretch}" Padding="{TemplateBinding Padding}" HorizontalContentAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalContentAlignment="{TemplateBinding VerticalContentAlignment}" /> </ScrollViewer> </Border> </ControlTemplate> </go:Diagram.Template> . . .
You may want to play with the implementation of the ComputeAutoScrollPosition to suit your needs. The default implementation, from which this code was adapted, changes the distance that it scrolls based on how close it is to the edge of the viewport. But this sample code always goes a fixed distance, a multiple of the Scroll…LineChange, regardless of how far outside of the viewport the mouse is.

This code also ignores AutoScrollMargin, which might not matter to you while you are overriding this method. So there is auto-scrolling only when the mouse is outside of the viewport, not along the inner edge.

And as you astutely pointed out, Diagram.AllowDragOut is false for this sample, which allows us to get meaningful events when the mouse is dragging outside of the viewport.

Thankyou very much for the solution. It works like a charm.

Another issue which still remains is when we drag a link out of the viewport, the autoscrolling begins.In this state of autoscrolling if we leave the mouse left button, the scrolling continues and there is no option to stop it.

This we checked using DynamicPorts sample.

But when we drag a node into the autoscroll region and if we leave the mouse button during autoscroll, there is no issue.
This happens only when dragging links.

This happens always whether or not the autoscroll region is inside (default) or outside (using the above solution).

I tried that in the Draggable Link sample, but I was unable to reproduce any problem.

What did you modify from the standard Dynamic Ports sample to be able to observe the problem?

When we drag out a link (in this case) or move the link to the auto-scroll region (default), the auto-scroll begins.
In this state, if we release the mouse button (when the background canvas is still moving), then the auto-scrolling doesn’t stop.

This happens only during auto-scroll of links, not with auto-scroll of nodes.

The Dynamic Ports sample does not support auto-scrolling when drawing a new link. In other words, the LinkingTool has not been modified to implement auto-scrolling.

Have you implemented this yourself? If so, did you override DoMouseMove to call Diagram.Panel.DoAutoScroll? And did you also override DoStop to call Diagram.Panel.StopAutoScroll?