We want to update a combobox so that it always shows the correct scale. If the user zooms-in, out or resizes the control hosting the map. What is the best event or events to catch and use in ArcGIS to update the scale?
Update1: Background I'm using the synchronization sample made by ESRI, and I can't find any event that handles the switching between map and layout. Tried using the MapControl ExtentUpdated event.
Public Function getScale() As Integer
Dim returnValue As Integer = Convert.ToInt32(axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation.ScaleRatio())
Return returnValue
End Function
Private Sub axMapControl1_OnExtentUpdated(ByVal sender As System.Object, ByVal e As ESRI.ArcGIS.Controls.IMapControlEvents2_OnExtentUpdatedEvent) Handles axMapControl1.OnExtentUpdated
TextBox1.Text = "Scale: " & getScale()
End Sub
Private Sub axPageLayoutControl1_OnExtentUpdated(ByVal sender As System.Object, ByVal e As ESRI.ArcGIS.Controls.IPageLayoutControlEvents_OnExtentUpdatedEvent) Handles axPageLayoutControl1.OnExtentUpdated
TextBox1.Text = "Scale: " & getScale()
End Sub
Update2: Tried the ITransformEvents but it doesn't work when switching map to pagelayout:
Private transformationEvents As ESRI.ArcGIS.Display.ITransformEvents_Event
Private m_transformationEventsAfterDraw As ESRI.ArcGIS.Display.ITransformEvents_VisibleBoundsUpdatedEventHandler
Private Sub wireEvent()
transformationEvents = CType(axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation, ESRI.ArcGIS.Display.ITransformEvents_Event)
m_transformationEventsAfterDraw = New ESRI.ArcGIS.Display.ITransformEvents_VisibleBoundsUpdatedEventHandler(AddressOf OnTransformEventsVisibleBoundsUpdated)
AddHandler CType(axMapControl1.ActiveView.ScreenDisplay.DisplayTransformation, ESRI.ArcGIS.Display.ITransformEvents_Event).VisibleBoundsUpdated, m_transformationEventsAfterDraw
End Sub
Private Sub OnTransformEventsVisibleBoundsUpdated(ByVal sender As ESRI.ArcGIS.Display.IDisplayTransformation, ByVal theSizeChanged As Boolean)
TextBox1.Text = "Scale: " & getScale()
End Sub
The result looks like this, the scalebar in the ESRI Toolbar is showing the layout scale but my textbox still shows the scale that was in the Map:
Update3: I tried this and now I get an Event when switching to the pagelayout but when I return to the map the scale is still way off:
Dim activeViewEventsMap As IActiveViewEvents_Event
Private m_ActiveViewEventsViewRefreshedMap As IActiveViewEvents_ViewRefreshedEventHandler
Private Sub wireActiveViewEventMap()
activeViewEventsMap = TryCast(axMapControl1.ActiveView.FocusMap, IActiveViewEvents_Event)
'Create an instance of the delegate, add it to ViewRefreshed event
m_ActiveViewEventsViewRefreshedMap = New IActiveViewEvents_ViewRefreshedEventHandler(AddressOf OnActiveViewEventsViewRefreshedMap)
AddHandler activeViewEventsMap.ViewRefreshed, m_ActiveViewEventsViewRefreshedMap
End Sub
Dim activeViewEventsPagelayout As IActiveViewEvents_Event
Private m_ActiveViewEventsViewRefreshedPagelayout As IActiveViewEvents_ViewRefreshedEventHandler
Private Sub wireActiveViewEventPagelayout()
activeViewEventsPagelayout = TryCast(axPageLayoutControl1.ActiveView.FocusMap, IActiveViewEvents_Event)
'Create an instance of the delegate, add it to ViewRefreshed event
m_ActiveViewEventsViewRefreshedPagelayout = New IActiveViewEvents_ViewRefreshedEventHandler(AddressOf OnActiveViewEventsViewRefreshedPagelayout)
AddHandler activeViewEventsPagelayout.ViewRefreshed, m_ActiveViewEventsViewRefreshedPagelayout
End Sub
Private m_scale As Integer = 0
Private Sub OnActiveViewEventsViewRefreshedMap(ByVal view As IActiveView, ByVal phase As esriViewDrawPhase, ByVal data As System.Object, ByVal envelope As IEnvelope)
Dim tempScale As Integer = getScaleMap()
If m_scale <> tempScale Then
TextBox1.Text = "Scale: " & tempScale
End If
m_scale = tempScale
End Sub
Private Sub OnActiveViewEventsViewRefreshedPagelayout(ByVal view As IActiveView, ByVal phase As esriViewDrawPhase, ByVal data As System.Object, ByVal envelope As IEnvelope)
Dim tempScale As Integer = getScalePagelayout()
If m_scale <> tempScale Then
TextBox1.Text = "Scale: " & tempScale
End If
m_scale = tempScale
End Sub
Public Function getScaleMap() As Integer
Dim returnValue As Integer
Dim control As IMapControl4 = CType(m_controlsSynchronizer.ActiveControl, IMapControl4)
returnValue = Convert.ToInt32(control.ActiveView.ScreenDisplay.DisplayTransformation.ScaleRatio())
Return returnValue
End Function
Public Function getScalePagelayout() As Integer
Dim returnValue As Integer
Dim control As IPageLayoutControl3 = CType(m_controlsSynchronizer.ActiveControl, IPageLayoutControl3)
returnValue = Convert.ToInt32(control.ActiveView.ScreenDisplay.DisplayTransformation.ScaleRatio())
Return returnValue
End Function
The solution: As far as I can see the only true way to catch when the scale is changed is by combining several methods, all of the above methods works if only a map or layout is used. The problem starts when used with the ESRI sync example, somehow the ESRI scale in the toolbar catches the switch between map and layout, probably because it is called when changing buddy control, but the only way to get the same behaviour is by using any of the above methods and adding a line of code that calculates and show the scale when the tab control event handler gets called, directly after the sync of the Map object to the active control.