Unfortunately it appears that the
AfterLayerDraw events are only fired by feature and network layers (see wguidry's post here) and I need to support raster layers, map/image services, mosaic datsets, etc.
So in a nutshell here is what I ended up doing. Thanks @Kirk again for the ideas!
Created the following classes:
Timing: Stores the layer name, draw phase and elapsed time for a drawing event
TimingSequence: Stores all the timings in a drawing sequence
TimingSession: Stores all of the timing sequences in a timing session and manages the
A timing session is started and stopped by a toggle button. When the timing session starts I enable
IViewManager.VerboseEvents and disable it when the timing session ends.
I reset and start the Stopwatch at the start of a drawing sequence as indicated by
IActiveViewEvents.ViewRefreshed and instantiate a new
Then, as each layer draws for a specific phase, I listen for
IActiveViewEvents.AfterItemDraw, stop the Stopwatch, check that
ITrackCancel.Continue() returns true (false indicates drawing was canceled) and record the layer name, phase and elapsed time in a new
Timing object and add it to the current
TimingSequence, and reset/restart the Stopwatch.
I only add a timing sequence to the timing session when
IActiveViewEvents.AfterDraw fires in the
esriViewForeground phase (the last drawing phase).
When the user ends the timing session by toggling the button again, I report the results (ideally it would be something nicer than an ugly MessageBox as it is now). It seems to be working smoothly though.
AfterItemDraw event only seems to fire for layers in the root of the table of contents, not nested sublayers, so if you want individual measurements for a layer it must be moved into the root of the TOC and not within a group layer. See linked question: ArcObjects: AfterItemDraw only fires for layers in the root of TOC