I would like to add a progress indicator to our ArcGIS Engine 10 application. Like a progressbar in the statusbar to show when the MapControl is busy getting or drawing the map. I've been trying to find any resources in the documentation on how to do this, but all resources I find is pointing to the MxStatusBar that is only in the ArcGIS Desktop. Does anyone know which events I should be using to create my own progress indicator?
Update: It's a standalone ArcGIS Engine Application. Built in VB.Net using WinForms. We've created the graphical animation for our busy indicator. So that we can start and stop the animation when there is progress. This was created using a dialog running in it's own thread because the MapControl block the redrawing of the form during it's draw phase. We've tried to hook up the busy indicator to AxMapControl1_OnBeforeScreenDraw and AxMapControl1_OnAfterScreenDraw events. But these events are thrown even when the map is repainted,for.ex. when a dialog is dragged over the map.
We've also tried manually using the IMapControlEvents2 and it gives the same result.
We have tried to add the IDisplayEvent but it only get triggered on start up not when we pan and zoom the map. Here is some code I used to test the events with:
'Declarations:
Private m_ActiveViewEventsAfterDraw As ESRI.ArcGIS.Carto.IActiveViewEvents_AfterDrawEventHandler
Private m_DisplayEventsDisplayStarted As ESRI.ArcGIS.Display.IDisplayEvents_DisplayStartedEventHandler
Private m_DisplayEventsDisplayFinished As ESRI.ArcGIS.Display.IDisplayEvents_DisplayFinishedEventHandler
Private m_MapControlEventsOnAfterScreenDraw As ESRI.ArcGIS.Controls.IMapControlEvents2_OnAfterScreenDrawEventHandler
Private m_MapControlEventsOnBeforeScreenDraw As ESRI.ArcGIS.Controls.IMapControlEvents2_OnBeforeScreenDrawEventHandler
'Form_Load
Dim mapControl As IMapControl4 = DirectCast(axMapControl1.Object, IMapControl4)
Dim map As IMap = DirectCast(axMapControl1.ActiveView, IMap)
m_ActiveViewEventsAfterDraw = New ESRI.ArcGIS.Carto.IActiveViewEvents_AfterDrawEventHandler(AddressOf OnActiveViewEventsAfterDraw)
AddHandler CType(map, ESRI.ArcGIS.Carto.IActiveViewEvents_Event).AfterDraw, m_ActiveViewEventsAfterDraw
m_DisplayEventsDisplayStarted = New ESRI.ArcGIS.Display.IDisplayEvents_DisplayStartedEventHandler(AddressOf OnDisplayStarted)
AddHandler CType(axMapControl1.ActiveView.ScreenDisplay, ESRI.ArcGIS.Display.IDisplayEvents_Event).DisplayStarted, m_DisplayEventsDisplayStarted
m_DisplayEventsDisplayFinished = New ESRI.ArcGIS.Display.IDisplayEvents_DisplayFinishedEventHandler(AddressOf OnDisplayFinished)
AddHandler CType(axMapControl1.ActiveView.ScreenDisplay, ESRI.ArcGIS.Display.IDisplayEvents_Event).DisplayFinished, m_DisplayEventsDisplayFinished
m_MapControlEventsOnAfterScreenDraw = New ESRI.ArcGIS.Controls.IMapControlEvents2_OnAfterScreenDrawEventHandler(AddressOf OnAfterScreenDraw)
AddHandler CType(axMapControl1.Object, ESRI.ArcGIS.Controls.IMapControlEvents2_Event).OnAfterScreenDraw, m_MapControlEventsOnAfterScreenDraw
m_MapControlEventsOnBeforeScreenDraw = New ESRI.ArcGIS.Controls.IMapControlEvents2_OnBeforeScreenDrawEventHandler(AddressOf OnBeforeScreenDraw)
AddHandler CType(axMapControl1.Object, ESRI.ArcGIS.Controls.IMapControlEvents2_Event).OnBeforeScreenDraw, m_MapControlEventsOnBeforeScreenDraw
'Methods
Private Sub OnAfterScreenDraw(ByVal hDc As Integer)
Console.WriteLine("OnAfterScreenDraw")
End Sub
Private Sub OnBeforeScreenDraw(ByVal hDc As Integer)
Console.WriteLine("OnBeforeScreenDraw")
End Sub
Private Sub OnActiveViewEventsAfterDraw(ByVal Display As ESRI.ArcGIS.Display.IDisplay, ByVal phase As ESRI.ArcGIS.Carto.esriViewDrawPhase)
Console.WriteLine("AfterDraw")
End Sub
Private IntDisplayStarted As Integer
Private Sub OnDisplayStarted(ByVal Display As IDisplay)
IntDisplayStarted = IntDisplayStarted + 1
Console.WriteLine("OnDisplayStarted " & IntDisplayStarted)
End Sub
Private IntDisplayFinished As Integer
Private Sub OnDisplayFinished(ByVal Display As IDisplay)
IntDisplayFinished = IntDisplayFinished + 1
Console.WriteLine("OnDisplayFinished " & IntDisplayFinished)
End Sub
Have also tried using the ILayerStatus by implementing the IStepProgressor callback on the MapServerLayer, but it was also a disapointment, it get triggered after the image has been fetched from the server.
Does anyone know if there is an event that we can use that only get triggered when the Map is getting data form its datasource?
Best Answer
The code below works for me. If you load a new map, you'll need to re-wire your events. Maybe try start animating when IDisplayEvents.Start fires (and IViewRefresh.Drawing is true). Then stop animating when IActiveViewEvents.AfterDraw fires with drawPhase == esriViewDrawPhase.esriViewForeground.