Hi AuroreErgole!
I had recently similar problems. I wrote the following code.
I hope it helps to solve your problem.
Lukas
/// <summary>
/// Moves the DiagramPanel.Viewport to the given Spot of the DiagramPanel without the DiagramPanel.Padding.
/// </summary>
/// <param name="viewSpot">the target-spot</param>
private void ShowSpot(Spot viewSpot)
{
DiagramPanel myPanel = myDiagram.Panel;
Thickness myPadding = myPanel.Padding;
double myScale = myPanel.Scale;
double diagramWidth = myPanel.ExtentWidth - (myPadding.Left + myPadding.Right) * myScale;
double diagramHeight = myPanel.ExtentHeight - (myPadding.Top + myPadding.Bottom) * myScale;
myPanel.SetHorizontalOffset(myPadding.Left * myScale + (diagramWidth - myPanel.ViewportWidth) * viewSpot.X - viewSpot.OffsetX * myScale);
myPanel.SetVerticalOffset(myPadding.Top * myScale + (diagramHeight - myPanel.ViewportHeight) * viewSpot.Y - viewSpot.OffsetY * myScale);
}
/// <summary>
/// Set the scale of the DiagramPanel that all Nodes fit into the DiagramPanel.Viewport.
/// If the scale would be less than <param name="minScale"/> the scale is set to <param name="minScale"/>.
/// If the scale would be greater than <param name="maxScale"/> the scale is set to <param name="maxScale"/>.
/// </summary>
/// <param name="minScale">The minimum scale that is allowed. If it is less than or equal to 0 it will be ignored.</param>
/// <param name="maxScale">The maximum scale that is allowed. If it is less than or equal to <param name="minScale"/> it will be ignored.</param>
/// <param name="emptyHorizontalSpace">The space that should be empty on the left and right side (altogether) of the nodes if possible without setting the scale less than <param name="minScale"/>.</param>
/// <param name="emptyVerticalSpace">The space that should be empty on the top and bottom side (altogether) of the nodes if possible without setting the scale less than <param name="minScale"/>.</param>
/// <returns>
/// 0 if the scale had been between <param name="minScale"/> and <param name="maxScale"/>.
/// -1 if the scale had been less than <param name="minScale"/>.
/// +1 if the scale had been greater than <param name="maxScale"/>.
/// </returns>
private int SetScale_AllNodesFitIntoViewport(double minScale, double maxScale, double emptyHorizontalSpace, double emptyVerticalSpace)
{
DiagramPanel myPanel = myDiagram.Panel;
Thickness myPadding = myPanel.Padding;
double optimalHorizontalScale = myPanel.ViewportWidth / (myPanel.DiagramBounds.Width - myPadding.Left - myPadding.Right + emptyHorizontalSpace);
double optimalVerticalScale = myPanel.ViewportHeight / (myPanel.DiagramBounds.Height - myPadding.Top - myPadding.Bottom + emptyVerticalSpace);
double optimalScale = optimalHorizontalScale <= optimalVerticalScale ? optimalHorizontalScale : optimalVerticalScale;
if (minScale > 0 && optimalScale < minScale)
{
myPanel.Scale = minScale;
return -1;
}
else if (maxScale > minScale && optimalScale > maxScale)
{
myPanel.Scale = maxScale;
return 1;
}
else
{
myPanel.Scale = optimalScale;
return 0;
}
}
Also, DiagramPanel.ComputeBounds will produce the union of the Part.Bounds. You just need to check for a return value of Rect.Empty, in case there weren’t any parts or if they didn’t have valid bounds.