private Envelope _constrainedExtent = null; private bool _hasExtentBeenSet = false; private Envelope _lastExtent = null; private void ConstraintExtent(object sender, ExtentEventArgs e) { var map = sender as Map; if (map == null) return; Envelope newExtent = e.NewExtent.Clone(); if (_constrainedExtent == null) // In this sample : initialize contrainted extent to first the extent _constrainedExtent = newExtent; if ((newExtent.XMin >= _constrainedExtent.XMin && newExtent.XMax <= _constrainedExtent.XMax && // completely within newExtent.YMin >= _constrainedExtent.YMin && newExtent.YMax <= _constrainedExtent.YMax) || (newExtent.XMin >= _constrainedExtent.XMin && newExtent.XMax <= _constrainedExtent.XMax && // width within and height outside newExtent.YMin <= _constrainedExtent.YMin && newExtent.YMax >= _constrainedExtent.YMax) || (newExtent.XMin <= _constrainedExtent.XMin && newExtent.XMax >= _constrainedExtent.XMax && // height within and width outside newExtent.YMin >= _constrainedExtent.YMin && newExtent.YMax <= _constrainedExtent.YMax)) { if (_hasExtentBeenSet) { _hasExtentBeenSet = false; map.ZoomTo(newExtent.Expand(0.999)); // hack to force the refresh of the layers } return; } if (newExtent.Equals(_lastExtent)) return; _lastExtent = newExtent; if (newExtent.Width <= _constrainedExtent.Width && newExtent.Height <= _constrainedExtent.Height) { // Pan enough to respect constraint double dx = Math.Min(_constrainedExtent.XMax - newExtent.XMax, Math.Max(_constrainedExtent.XMin - newExtent.XMin, 0)); double dy = Math.Min(_constrainedExtent.YMax - newExtent.YMax, Math.Max(_constrainedExtent.YMin - newExtent.YMin, 0)); newExtent.XMin += dx; newExtent.XMax += dx; newExtent.YMin += dy; newExtent.YMax += dy; map.PanTo(newExtent); } else { // Change extent to respect constraint newExtent = newExtent.Intersection(_constrainedExtent); map.Extent = newExtent; _hasExtentBeenSet = true; } }