How to plug in dynamic drawing


Summary
With the dynamic display application programming interface (API), the following is where dynamic drawing can be plugged in—have a custom layer implement the IDynamicLayer interface. Draw the dynamic items on the IDynamicLayer.DrawDynamicLayer method and listen to dynamic display events (IDynamicMapEvents.AfterDynamicDraw and IDynamicMapEvents.BeforeDynamicDraw).


Implementing the IDynamicLayer.DrawDynamicLayer method

Do the following steps to implement the IDynamicLayer.DrawDynamicLayer method:
  1. Override the DrawDynamicLayer method. See the following code example:
[C#]
public override void DrawDynamicLayer(esriDynamicDrawPhase DynamicDrawPhase,
    IDisplay Display, IDynamicDisplay DynamicDisplay){}
[VB.NET]
Public Overrides Sub DrawDynamicLayer(ByVal DynamicDrawPhase As esriDynamicDrawPhase, ByVal Display As IDisplay, ByVal DynamicDisplay As IDynamicDisplay)
End Sub
  1. Ensure the dynamic display draw phase is immediate. See the following code example:
[C#]
if (DynamicDrawPhase != esriDynamicDrawPhase.esriDDPImmediate)
    return ;
[VB.NET]
If DynamicDrawPhase <> esriDynamicDrawPhase.esriDDPImmediate Then
    Return
End If
The following are the two draw phases for dynamic display:
  • Compiled (esriDDPCompiled)—Use the compiled draw phase when data is less dynamic by nature.
  • Immediate (esriDDPImmediate)—Use the immediate draw phase when data is highly dynamic and changes need to take place immediately.
Ensure the dynamic layer is only drawing in one of the two draw phases; otherwise, it draws twice on each drawing cycle.
  1. Ensure the layer is valid and visible. See the following code example:
[C#]
if (!m_bValid || !m_visible)
    return ;
[VB.NET]
If (Not m_bValid) OrElse (Not m_visible) Then
    Return
End If
Both m_bValid and m_visible are class members of BaseDynamicLayer, which is part of the ESRI.ArcGIS.ADF.BaseClasses assembly.
  1. Do a one-time initialization. Obtain DynamicGlyphFactory and DynamicSymbolProperties only once from the DynamicDisplay. See the following code example:
[C#]
if (m_bOnce)
{
    m_dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory;
    m_dynamicSymbolProps = DynamicDisplay as IDynamicSymbolProperties;
    CreateMarkerGlyph();
    m_bOnce = false;
}
[VB.NET]
If m_bOnce Then
    m_ dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory
    m_dynamicSymbolProps = TryCast(DynamicDisplay, IDynamicSymbolProperties)
    CreateMarkerGlyph()
    m_bOnce = False
End If
  1. Draw dynamic content on the dynamic layer. See the following code example:
[C#]
m_dynamicSymbolProps.set_DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker,
    m_myGlyph);
m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f,
    0.0f, 1.0f);
m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f);
DynamicDisplay.DrawMarker(m_point);
[VB.NET]
m_dynamicSymbolProps.DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker) = m_myGlyph
m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f, 0.0f, 1.0f)
m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f)
DynamicDisplay.DrawMarker(m_point)
  1. Set the dirty flag to false to signal that drawing is done. See the following code example:
[C#]
base.m_bIsImmediateDirty = false;
[VB.NET]
MyBase.m_bIsImmediateDirty = False
Setting the dynamic layer's dirty flag to true signals the dynamic display that the layer needs to be redrawn. According to the draw phase that your dynamic layer supports, set the appropriate draw flag to true only when an item of your layer gets updated.
See the following complete code example:
 
[C#]
public override void DrawDynamicLayer(esriDynamicDrawPhase DynamicDrawPhase,
    IDisplay Display, IDynamicDisplay DynamicDisplay)
{
    if (DynamicDrawPhase != esriDynamicDrawPhase.esriDDPImmediate)
        return ;
    if (!m_bValid || !m_visible)
        return ;
    if (m_bOnce)
    {
        m_dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory;
        m_dynamicSymbolProps = DynamicDisplay as IDynamicSymbolProperties;
        CreateMarkerGlyph();
        m_bOnce = false;
    }
    m_dynamicSymbolProps.set_DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker,
        m_myGlyph);
    m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f,
        0.0f, 0.0f, 1.0f);
    m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f,
        1.0f);
    DynamicDisplay.DrawMarker(m_point);

    base.m_bIsImmediateDirty = false;
}
[VB.NET]
Public Overrides Sub DrawDynamicLayer(ByVal DynamicDrawPhase As esriDynamicDrawPhase, ByVal Display As IDisplay, ByVal DynamicDisplay As IDynamicDisplay)

If DynamicDrawPhase <> esriDynamicDrawPhase.esriDDPImmediate Then
    Return
End If
If (Not m_bValid) OrElse (Not m_visible) Then
    Return
End If
If m_bOnce Then
    m_dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory
    m_dynamicSymbolProps = TryCast(DynamicDisplay, IDynamicSymbolProperties2)
    CreateMarkerGlyph()
    m_bOnce = False
End If
m_dynamicSymbolProps.DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker) = m_myGlyph
m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f, 0.0f, 1.0f)
m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f)
DynamicDisplay.DrawMarker(m_point)

MyBase.m_bIsImmediateDirty = False
End Sub

Listening to the IDynamicMapEvents.AfterDynamicDraw event

Do the following steps to listen to the IDynamicMapEvents.AfterDynamicDraw event:
  1. Wire the AfterDynamicDraw event. See the following code example:
[C#]
((IDynamicMapEvents_Event)m_dynamicMap).AfterDynamicDraw += new
    IDynamicMapEvents_AfterDynamicDrawEventHandler(OnAfterDynamicDraw);
[VB.NET]
AddHandler (CType(m_dynamicMap, IDynamicMapEvents_Event)).AfterDynamicDraw, AddressOf OnAfterDynamicDraw
  1. Implement the event handler OnAfterDynamicDraw method. See the following code example:
[C#]
public void OnAfterDynamicDraw(esriDynamicMapDrawPhase dynamicMapDrawPhase, IDisplay
    Display, IDynamicDisplay dynamicDisplay){}
[VB.NET]
Private Sub OnAfterDynamicDraw(ByVal DynamicMapDrawPhase As esriDynamicMapDrawPhase, ByVal Display As IDisplay, ByVal dynamicDisplay As IDynamicDisplay)
End Sub
  1. Ensure the dynamic map draw phase is dynamic layers. See the following code example:
[C#]
if (DynamicMapDrawPhase != esriDynamicMapDrawPhase.esriDMDPDynamicLayers)
    return ;
[VB.NET]
If (DynamicMapDrawPhase <>esriDynamicMapDrawPhase.esriDMDPDynamicLayers)
    Return
End If
The following are the two draw phases of dynamic map (the AfterDynamicDraw and BeforeDynamicDraw events can get fired with either draw phase):
  • esriDMDPDynamicLayers—Fired on each dynamic cycle when the dynamic map renders the scene again.
  • esriDMDPLayers—Fired when the dynamic map fetches tiles to render the scene.
  1. Do a one-time initialization. Obtain DynamicGlyphFactory and DynamicSymbolProperties only once from the DynamicDisplay. See the following code example:
[C#]
if (m_bOnce)
{
    m_dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory;
    m_dynamicSymbolProps = DynamicDisplay as IDynamicSymbolProperties;
    CreateMarkerGlyph();
    m_bOnce = false;
}
[VB.NET]
If m_bOnce Then
    
    m_dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory
    m_dynamicSymbolProps = TryCast(DynamicDisplay, IDynamicSymbolProperties)
    CreateMarkerGlyph()
    m_bOnce = False
End If
  1. Draw the dynamic content on top of the map. See the following code example:
[C#]
m_dynamicSymbolProps.set_DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker,
    m_myGlyph);
m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f,
    0.0f, 1.0f);
m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f);
DynamicDisplay.DrawMarker(m_point);
[VB.NET]
m_dynamicSymbolProps.DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker) = m_myGlyph
m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f, 0.0f, 1.0f)
m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f)
DynamicDisplay.DrawMarker(m_point)
  • IDynamicLayer.DrawDynamicLayer draws dynamic content to a layer.
  • IDynamicMapEvents.AfterDynamicDraw draws dynamic content on top all of the map's layers.
See the following complete code example:
[C#]
public void OnAfterDynamicDraw(esriDynamicMapDrawPhase dynamicMapDrawPhase, IDisplay
    Display, IDynamicDisplay dynamicDisplay)
{
    if (DynamicMapDrawPhase != esriDynamicMapDrawPhase.esriDMDPDynamicLayers)
        return ;
    if (m_bOnce)
    {
        m_dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory;
        m_dynamicSymbolProps = DynamicDisplay as IDynamicSymbolProperties;
        CreateMarkerGlyph();
        m_bOnce = false;
    }
    m_dynamicSymbolProps.set_DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker,
        m_myGlyph);
    m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f,
        0.0f, 0.0f, 1.0f);
    m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f,
        1.0f);

    DynamicDisplay.DrawMarker(m_point);
}
[VB.NET]
Private Sub OnAfterDynamicDraw(ByVal DynamicMapDrawPhase As esriDynamicMapDrawPhase, ByVal Display As IDisplay, ByVal dynamicDisplay As IDynamicDisplay)
    If (DynamicMapDrawPhase <>esriDynamicMapDrawPhase.esriDMDPDynamicLayers)
        Return
    End If
    If m_bOnce Then
        m_dynamicGlyphFactory = DynamicDisplay.DynamicGlyphFactory
        m_dynamicSymbolProps = TryCast(DynamicDisplay, IDynamicSymbolProperties2)
        CreateMarkerGlyph()
        m_bOnce = False
    End If
    m_dynamicSymbolProps.DynamicGlyph(esriDynamicSymbolType.esriDSymbolMarker) = m_myGlyph
    m_dynamicSymbolProps.SetColor(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 0.0f, 0.0f, 1.0f)
    m_dynamicSymbolProps.SetScale(esriDynamicSymbolType.esriDSymbolMarker, 1.0f, 1.0f)
    
    DynamicDisplay.DrawMarker(m_point)
End Sub
IDynamicMapEvents.AfterDynamicDraw event is fired each time the dynamic display finishes drawing all layers, including graphics layers. Unwire the event from your application when you no longer need to listen to it.


See Also:

Walkthrough: Getting started with dynamic display
Best practices for using dynamic display
How to wire ArcObjects .NET events
Sample: Dynamic display layer
Sample: Dynamic display—tracking dynamic object
How to create a dynamic glyph from a marker symbol




To use the code in this topic, reference the following assemblies in your Visual Studio project. In the code files, you will need using (C#) or Imports (VB .NET) directives for the corresponding namespaces (given in parenthesis below if different from the assembly name):
Additional Requirements
  • Implement a dynamic layer through inheritance of DynamicLayerBase, which is part of the ESRI.ArcGIS.ADF.Local assembly in the ESRI.ArcGIS.ADF.BaseClasses namespace.
  • Class member m_myGlyph is declared as IDynamicGlyph and created by the CreateMarkerGlyph() method.
  • Class member m_bOnce is a Boolean and set to true initially.
  • Class member m_point is declared as IPoint and is initialized.
  • Class member m_dynamicGlyphFactory is declared as IDynamicGlyphFactory.
  • Class member m_dynamicSymbolProps is declared as IDynamicSymbolProperties.
  • Class member m_dynamicMap is declared as IDynamicMap and is initialized.

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