Take the 2-minute tour ×
Geographic Information Systems Stack Exchange is a question and answer site for cartographers, geographers and GIS professionals. It's 100% free, no registration required.

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 doesen'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: Wrong scale in textbox

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 workes 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 behavior 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 get called, directly after the sync of the Map object to the active control.

share|improve this question
add comment

2 Answers

up vote 3 down vote accepted

Please note that ITransformEvents.VisibleBoundsUpdated also does not fire when you resize the map's frame element on page layout, which is an action that can change scale as well.

I personally ended up listening for IActiveViewEvents.ViewRefreshed on BOTH the map and the page layout. As this event fires very frequently (and for each uncached draw phase), I keep track of previous map scale and fire an action only when the current scale actually differs.

share|improve this answer
    
I thought that this worked, but it seems like I hit a new problem and that is getting the correct scale. –  MathiasWestin Sep 22 '10 at 14:16
add comment

You are looking for an "event" which gets raised when the scale changes. You attach your subroutine/method to the event and that method gets fired every time the event happens. In your case you would attach a method like UpdateScaleUI() to the ScaleChangedEvent (or what ever it happens to be called, I haven't found it in the documents yet).

This is a discussion in a forum over at ESRI with sample code.

share|improve this answer
    
Yes, I know it's all about finding it in the documentation. Which isn't the easiest of tasks :) –  MathiasWestin Sep 21 '10 at 15:38
2  
Found it, it's the ITransformEvents you refering to help.arcgis.com/en/sdk/10.0/arcobjects_net/componenthelp/… –  MathiasWestin Sep 21 '10 at 15:44
    
Well done! If you put all your info into a good answer, I'll vote you up and delete this one. –  yhw42 Sep 21 '10 at 16:01
    
Well it workes, but not fully, I'm not sure why the switching between map and layout in the synchronization sample doesn't fire the events. –  MathiasWestin Sep 21 '10 at 17:59
    
Do the map event and the layout events have the same signature? (there might be an implicit cast or something... I'm just guessing) –  yhw42 Sep 21 '10 at 19:21
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.