I have written a simple tool to pan a viewer window (if present) to the centre of the map view, which reduces the number of clicks required and mouse travel to Pan Viewer to Map Location, it works mostly as anticipated but if the scale of the map viewer is set to a round number (in this case 24000) the scale is expanded on the first use but not on 3rd or subsequent uses: Scale set before running. Scale after running first time. Scale for further instances.
The code:
IPoint CentreOfScreen = new PointClass();
IPoint CentreOfInset = new PointClass();
// derive the centre of the map from the active view extent
IEnvelope pMapExtent = ArcMap.Document.ActiveView.Extent;
CentreOfScreen.PutCoords((pMapExtent.XMax + pMapExtent.XMin) / 2,(pMapExtent.YMax + pMapExtent.YMin) / 2);
// get the application windows, could be of a few
// types but we'll filter the one we want later
IApplicationWindows pAppWin = (IApplicationWindows)ArcMap.Application;
ISet pDatWindows = pAppWin.DataWindows;
// reset the enumeration and get the first object so that it's not null
// Leaving pDatWin unset will mean the loop will not progress
pDatWindows.Reset();
Object pDatWin = pDatWindows.Next();
while (pDatWin != null)
{
if (pDatWin is IMapInsetWindow)
{
// this is the type of data window we want, not an overview window
IMapInsetWindow pInsWin = (IMapInsetWindow)pDatWin;
IMapInset pIns = pInsWin.MapInset;
double pPreScale = 0;
if (pIns.UsingZoomScale)
{
pPreScale = pIns.ZoomScale; // is set correctly
}
// derive the centre of the map viewer from its visible bounds
IEnvelope pExt = pIns.VisibleBounds;
CentreOfInset.PutCoords((pExt.XMax + pExt.XMin) / 2, (pExt.YMax + pExt.YMin) / 2);
// find how far to move the edges of the extent by finding the displacement
// of the centre of screen to the centre of the map viewer
double dX = CentreOfScreen.X - CentreOfInset.X;
double dY = CentreOfScreen.Y - CentreOfInset.Y;
// apply the offset to a new envelope
IEnvelope pNewExt = new EnvelopeClass();
pNewExt.PutCoords(pExt.XMin + dX, pExt.YMin + dY,
pExt.XMax + dX, pExt.YMax + dY);
// assert the new extent on the inset
pIns.VisibleBounds = pNewExt;
if (pIns.UsingZoomScale)
{
pIns.ZoomScale = pPreScale; // again set correctly
}
pInsWin.MapInset = pIns; // reset the inset window map inset
// refresh and yield until the inset is redrawn
pInsWin.Refresh();
System.Windows.Forms.Application.DoEvents();
}
pDatWin = pDatWindows.Next(); // go to the next data window
}
Reasserting the scale seems to have no effect; The math is fairly simple so it's unlikely I'm making a mistake there, if there were a mistake in the math I would expect the extent to keep growing on 2nd and subsequent iterations.
Has anyone who has worked with a viewer window in ArcObjects that can establish why the scale changes and knows how to keep the original scale?
PanStart
,PanMoveTo
,PanStop
onIMapInsetWindow.ScreenDisplay
?pIns.VisibleBounds
, did you try callingpIns.CalculateVisibleBounds()
?