Display events


Summary
This topic describes the events that are fired when a map draws. To provide better insight into drawing events, drawing order and display caching are also discussed.


Drawing order

To better understand the events that are fired when a map draws, the following describes the order in which objects are drawn for each view (Map and PageLayout):
  • Map (data view)—The following table shows top-to-bottom order (each item is drawn above the items beneath it):
Object
Phase
Cache
Graphic selection esriViewForeground none
Clip border esriViewForeground none
Feature selection esriViewGeoSelection selection
Auto labels esriViewGraphics annotation
Graphics esriViewGraphics annotation
Layer annotation esriViewGraphics annotation
Layers esriViewGeography layer or layers
Background esriViewBackground bottom layer
  • PageLayout—The following table shows top-to-bottom order (each item is drawn above the items beneath it):
Object
Phase
Cache
Snap guides esriViewForeground none
Selection esriViewGraphicSelection selection
Elements esriViewGraphics element
Snap grid esriViewBackground element
Print margins esriViewBackground element
Paper esriViewBackground element

Drawing events

The following IActiveViewEvents can be used to add custom drawing to your application:
  • AfterDraw(display, esriViewBackground)
  • AfterDraw(display, esriViewGeography)
  • AfterDraw(display, esriViewGeoSelection)
  • AfterDraw(display, esriViewGraphics)
  • AfterDraw(display, esriViewGraphicSelection)
  • AfterDraw(display, esriViewForeground)
  • AfterItemDraw(display, idx, esriDPGeography)
  • AfterItemDraw(display, idx, esriDPAnnotation)
  • AfterItemDraw(display, idx, esriDPSelection)
The AfterDraw event is fired after every phase of drawing. Do the following to draw a graphic into a cache:
  1. Create an object that connects to the active view (map); for example, Events.
  2. Choose the draw phase that you want to draw after. The phase you choose determines what is drawn above and below you.
  3. Draw in response to IActiveViewEvents.AfterDraw.
Not all the views fire all the events. Additionally, if a view is partially refreshed, the phases that draw from cache do not fire their AfterDraw event. For example, if the selection is refreshed, all the layers draw from cache. As a result, the AfterDraw(esriViewGeography) event does not fire; however, there is an exception. In the case of esriViewForeground, the event is fired every time the view draws. Even if everything in the map draws from the recording cache, the foreground event still fires.

Enabling item events with VerboseEvents

The AfterItemDraw event is fired after each feature or graphic is displayed and can seriously impact drawing performance if a connected handler is not efficient. Normally, clients connect to the AfterDraw event.
It is important to check the second argument and respond to the appropriate phase of drawing since the AfterDraw routine will be called several times when the map is drawn.
For efficiency, IActiveView has a VerboseEvents property. It can be used to limit the number of events that are fired. If VerboseEvents = false, AfterItemDraw is not fired (this is the default setting).

Events and display caching

The following tables show the handle device context (HDC) that is active when each of the AfterDraw events is fired:
Event
Active HDC
esriViewForeground window
esriViewGraphics annotation cache
esriViewGeoSelection selection cache
esriViewGeography top layer cache
esriViewBackground bottom layer cache
Event
Active HDC
esriViewForeground window
esriViewGraphicSelection selection cache
esriViewGraphics element cache
esriViewBackground element cache

Creating a private cache

For drawing graphics (events), you may want to use esriViewGraphics. AfterDraw has two arguments: pDisplay and drawPhase. It is called for each of the phases, so make sure you only draw when your phase is specified. Draw directly to the display and do not worry about caches. The StartDrawing and FinishDrawing methods are called by map. If the phase you are drawing after is cached, your drawing is automatically cached. See the following:
  • Create the cache in response to IDocumentEvents.ActiveViewChanged. Map creates its cache in response to Activate and throws away all caches in response to Deactivate. The ActiveViewChanged event is fired after map creates its cache, so if there is not enough memory, the map gets its cache but the private cache doesn't. See the following code example:
[C#]
IActiveView pActiveView = pMap as IActiveView;
IScreenDisplay pScreen = pActiveView.ScreenDisplay;
pScreen.AddCache(m_myCacheID);
[VB.NET]
Dim pActiveView As IActiveView = CType(pMap, ActiveView)
Dim pScreen As IScreenDisplay = pActiveView.ScreenDisplay
pScreen.AddCache(m_myCacheID)
  • AfterDraw looks like the following code example:
[C#]
if (phase != esriViewXXX)
{
    return ;
}

IScreenDisplay pScreen = pDisplay;

if ((!(pScreen == null)))
{
    // Draw directly to output device.
    DrawMyStuff(pDisplay);
    return ;
}

// Draw to screen using cache if possible.
long hWindowDC;
WindowDC = pScreen.WindowDC;

bool bDirty;
pScreen.IsCacheDirty(m_myCacheID, bDirty);
if ((bDirty))
{
    // Draw from scratch.
    pScreen.FinishDrawing();
    pScreen.StartDrawing(hWindowDC, m_myCacheID);
    DrawMyStuff(pDisplay);
}

else
{
    // Draw from cache.
    pScreen.DrawCache(hWindowDC, m_myCacheID, null, null);
}
[VB.NET]
If Not (phase = esriViewXXX) Then
    Return
End If

Dim pScreen As IScreenDisplay = pDisplay

If (Not (pScreen Is Nothing)) Then
    
    ' Draw directly to output device.
    DrawMyStuff(pDisplay)
    Return
    
End If

' Draw to screen using cache if possible.
Dim hWindowDC As Long
WindowDC = pScreen.WindowDC

Dim bDirty As Boolean
pScreen.IsCacheDirty(m_myCacheID, bDirty)

If (bDirty) Then
    
    ' Draw from scratch.
    pScreen.FinishDrawing()
    pScreen.StartDrawing(hWindowDC, m_myCacheID)
    DrawMyStuff(pDisplay)
    
Else
    
    ' Draw from cache.
    pScreen.DrawCache(hWindowDC, m_myCacheID, Nothing, Nothing)
    
End If

Transform events

The ITransformEvents interface provides access to display transformation events. ITransformEvents have their counterparts in the properties of the IDisplayTransformation.

For instance, ITransformEvents.BoundsUpdated is fired when IDisplayTransformation.Bounds is set. For information on these properties and the related ITransformEvents, refer to the documentation for IDisplayTransformation. See the following illustration:
 
One scenario in which ITransformEvents is useful is when implementing a custom graphic element. By sinking the outbound ITransformEvents interface of the DisplayTransformation, you can update the custom element to reflect changes, such as the data frame being rotated. You can also use ITransformEvents to update the element's selection tracker geometry correctly when the map scale changes.






Development licensing Deployment licensing
ArcGIS for Desktop Basic ArcGIS for Desktop Basic
ArcGIS for Desktop Standard ArcGIS for Desktop Standard
ArcGIS for Desktop Advanced ArcGIS for Desktop Advanced
Engine Developer Kit Engine