I would like to make an icon on the screen and have hover popup text. Ideally the text will be black with a white background.

Right now my icon is a bitmap created like this

GraphicTrackerClass incidentIcons = new GraphicTrackerClass();
incidentIcons.Initialize(mapControl.Map as IBasicMap);
int graphicID = incidentIcons.Add(thisIncident.point, alertIcon);

Then I set up a hit test and would like a text popup when I hover over the GraphicTracker (should I use a different class for displaying the icon?).

AxMapControl.DrawText is fast, but I can't figure out how to customize the text and background

MapTips look really cool but I can't find a function to plot a maptip with a point and text - I've only found layer.ShowTips = true;

I tried creating a balloon callout and activating my IElement like this (but it is really slow about 2 seconds for the popup to appear) :

pGraphicsContainer = activeView as IGraphicsContainer; 
pGraphicsContainer.AddElement(pElement, 0);
activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pElement, null);

I also had a bad experience experimenting with dynamicdisplay.

Below I've left the original post in case anybody wants to read it:

What are the main steps to use to improve performance for an arcengine hosted in WPF with C#. It's super slow. I made a bunch of layer invisible which helped but its still no where near being snappy / usable.


I load DataMaps10/streets_na/StreetMap North America.mxd and turn make the following layers invisible

CanadaBoundaries, CoastalWater, Parks, Airports, Landmarks, UrbanAreas, USBoundaries(World-25m), USBoundaries(25-1.5m), USBoundaries(1.5m-0), CanadaBoundaries, CanadaCoastlineandProvinces(World-25m), CanadaCoastline(25m-0), CanadaProvinces(25-1.5m), CanadaProvinces(1.5m-0), Exits(Numbers)(15k-0)

I haven't tried switching to Winforms, I don't exactly know how to do that.

Edit 3:

SO the problem is DynamicDisplayEnabled = true ruins EVERYTHING!

so I turn it off... but now I want text that pops up when you hover over something... I was going to use dyanmic display for that, but dynamic display turns everything to crap ! I'm super frustrated.

  • Can you describe in more detail what you set up looks like, what type of layers? Is there any difference if you switch to WinForm? Commented Sep 14, 2010 at 18:03
  • @iterationx Try creating a new project usig the MapControl template in VS. Commented Sep 14, 2010 at 19:08
  • How are you getting your data? ArcGIS Server feeds? SDE? Commented Sep 14, 2010 at 19:17
  • @Michael Todd I am just loaded a MXD file found in the DataMaps 10 .ISO discs
    – patrick
    Commented Sep 14, 2010 at 19:51
  • 3
    Since you've posted few questions which seem to be tightly related, perhaps it would be best to describe more generally what you are trying to achieve. From the questions I get the impression you probably do not need to use dynamic display at all..
    – Petr Krebs
    Commented Sep 15, 2010 at 8:37

3 Answers 3


Did you try putting these layers into a Basemap layer?

This is something new with 10.0, so there's not a lot of documentation.

Or, instead of using Streetmap USA, you might want to use a layer that points to ESRI's tiled map service, which I think was generated using similar data. I've put a .lyr file here that you can download. Here's a summary of what's in the lyr file:

Data Type:  ArcGIS Map Service
Connection:     Internet
Server:     http://services.arcgisonline.com/ArcGIS/services
Name:   ESRI_StreetMap_World_2D
Operations Allowed:     Map (Display)
Map Service Type:   Cached
File Format:    JPEG
Restriction:    Sublayers can't be turned on or off

Or, if you want to use WPF, you might look into the ArcGIS WPF/Silverlight SDK, a free download.

  • Thanks for the layer, one of my requirements, however, is that it must not depend on an internet connection.
    – patrick
    Commented Sep 16, 2010 at 19:27
  • 1
    I thought I recalled ESRI saying that at 10.0 they would allow a way to add a layer to a map that points to a local tile cache. I can't find any documentation though. That might make a good question: "Can I add a layer that uses a local tilecache directory?" Commented Sep 16, 2010 at 19:39
  • 2
    Ahh, "Disconnected Tile Cache" is what I was looking for. You'll need lot of disk space though. And lots of patience generating it. "Starting at version 10, ArcMap can read tile caches from disk as if they were any other raster dataset." help.arcgis.com/en/arcgisserver/10.0/help/… Commented Sep 16, 2010 at 19:42

Turn of the DynamicDisplay if your are not using it for animation (having graphics that is moving on the screen). It's possible to add graphics to the map without the DynamicDisplay. I showed you how to add a Balloon Callout in this thread without dynamic display. Or are you trying to do MapTips?

Some sample code on MapTips:

Private Sub AddMapTipsToolStripMenuItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles AddMapTipsToolStripMenuItem.Click
        Dim control As IMapControl4 = CType(axMapControl1.Object, IMapControl4)
        Dim map As IMap = control.Map

        If (map.LayerCount > 0) Then
            Dim layer As ILayer = map.Layer(0)

            layer.ShowTips = True

            SetDisplayField(layer, "Name")

            control.ShowMapTips = True
            MsgBox("Missing Layer")
        End If

    End Sub

    Private Sub SetDisplayField(ByVal layer As ILayer, ByVal displayField As String)
        If TypeOf layer Is IFeatureLayer2 Then
            Dim featureLayer As IFeatureLayer2 = CType(layer, IFeatureLayer2)
            featureLayer.DisplayField = displayField
        End If
    End Sub

Made a sample using a custom tool and Balloon Callout to show how it could be done if one have a point layer and only want to show text from the features.

 Public Overrides Sub OnMouseMove(ByVal Button As Integer, ByVal Shift As Integer, ByVal X As Integer, ByVal Y As Integer)


        'TODO: Add Tool1.OnMouseMove implementation
        Dim dispTransp As IDisplayTransformation = m_hookHelper.ActiveView.ScreenDisplay.DisplayTransformation
        Dim point As IPoint '= New ESRI.ArcGIS.Geometry.Point()

        point = dispTransp.ToMapPoint(X, Y)

        'Console.WriteLine(String.Format("{0}, {1}  {2}", point.X.ToString("#######.##"), point.Y.ToString("#######.##"), m_hookHelper.FocusMap.MapUnits.ToString().Substring(4)))

        If (m_hookHelper.FocusMap.LayerCount > 0) Then
            Dim layer As ILayer = m_hookHelper.FocusMap.Layer(0)

            If TypeOf layer Is IFeatureLayer Then
                Dim flayer As IFeatureLayer = CType(layer, IFeatureLayer)

                Dim spatialFilter As ISpatialFilter = New SpatialFilter()
                Dim polygon As IPolygon = CType((CType(point, ITopologicalOperator).Buffer(1.0)), IPolygon)
                spatialFilter.Geometry = polygon
                spatialFilter.WhereClause = ""
                spatialFilter.SpatialRel = esriSpatialRelEnum.esriSpatialRelContains
                Dim featCur As IFeatureCursor = flayer.Search(spatialFilter, False)

                Dim feat As IFeature = featCur.NextFeature()

                If Not feat Is Nothing Then
                    Dim s As String = feat.Value(feat.Fields.FindField("Name")).ToString()
                    AddBalloonCallout(m_hookHelper.ActiveView, s, CType(feat.Shape, IPoint).X, CType(feat.Shape, IPoint).Y)
                End If

            End If
        End If

    End Sub

    Private Sub removeBalloonCallout(ByVal activeView As IActiveView)
        Dim pGraphicsContainer As IGraphicsContainer
        Dim pElement As IElement
        pGraphicsContainer = CType(activeView, IGraphicsContainer)
        pElement = pGraphicsContainer.Next()

        If Not pElement Is Nothing Then

            'Flag the area of the new element for refreshing
            activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pElement, Nothing)

        End If
    End Sub

    Private Sub AddBalloonCallout(ByVal activeView As IActiveView, ByVal text As String, ByVal x As Double, ByVal y As Double)
        Dim pTextElement As ITextElement
        Dim pElement As IElement
        Dim pPoint As IPoint
        Dim pCallout As ICallout
        Dim pTextSymbol As IFormattedTextSymbol
        Dim pGraphicsContainer As IGraphicsContainer
        Dim midX As Double, midY As Double

        'Create a new text element
        pTextElement = New TextElement
        pElement = CType(pTextElement, IElement) 'QI
        pTextElement.Text = "Text callout" & vbCrLf & text

        'Position the new element on the active view's center point
        midX = (activeView.Extent.XMax + activeView.Extent.XMin) / 2
        midY = (activeView.Extent.YMax + activeView.Extent.YMin) / 2
        pPoint = New ESRI.ArcGIS.Geometry.Point
        pPoint.PutCoords(midX, midY)
        pElement.Geometry = pPoint

        'Set the text element symbology to a default balloon callout
        pTextSymbol = New ESRI.ArcGIS.Display.TextSymbol
        pCallout = New BalloonCallout
        pTextSymbol.Background = CType(pCallout, ITextBackground)
        'Use this formula to get a callout anchor point location
        pPoint.PutCoords(x, y)
        pCallout.AnchorPoint = pPoint
        pTextElement.Symbol = pTextSymbol

        'Add the element to the active view, either the focus Map or PageLayout
        pGraphicsContainer = CType(activeView, IGraphicsContainer)
        pGraphicsContainer.AddElement(pElement, 0)

        'Flag the area of the new element for refreshing
        activeView.PartialRefresh(esriViewDrawPhase.esriViewGraphics, pElement, Nothing)
    End Sub
  • The balloon callout works but it is pretty slow. I tried the MapTips sample, but I can't find a function to put text on a point, all I see in the code is layer.ShowTips = true; which doesn't give me enough control. I basically want some text to popup when I hover over an object and for it to not be tremendously slow.
    – patrick
    Commented Sep 16, 2010 at 19:20
  • 1
    @iterationx, That's the question you should ask: "How do I make some text to popup when I hover over an object and for it to not be tremendously slow." and define the context in which you want to do this. Commented Sep 16, 2010 at 20:18

The trick is to definately not cast anything into an IGraphicsContainer, since that is slow, what ended up being pretty fast is learning how to customize the DrawText function. I will post some code for posterity's sake.

//Init Code do this once 

   ////////////////////////////////balloon callout formatting//////////////////////////
   IBalloonCallout balloonCallout = new BalloonCalloutClass();
   pTextElement = new TextElementClass(); //pTextElement is an ITextElement
   pFormattedTextSymbol = new TextSymbol() as IFormattedTextSymbol; 
   TextSymbolClass textSymbolclass = new TextSymbolClass();
   textSymbolclass.Background = balloonCallout as ITextBackground; //the bare minimum
   balloonCallout.Style = esriBalloonCalloutStyle.esriBCSRoundedRectangle;
   textsymbol = textSymbolclass as ITextSymbol;
   textsymbol.Font = ESRI.ArcGIS.ADF.Connection.Local.Converter.ToStdFont(new Font("Arial", 10.0f, System.Drawing.FontStyle.Regular));
   ////////////////////////////////balloon callout formatting//////////////////////////
   //end init code

public void Draw(IPoint displayPoint, String description)
       ISymbol thissymbol = textsymbol as ISymbol;//textsymbol was init'd to a balloon callout above
       object thisobj = thissymbol as object;
       mapControl.DrawText(displayPoint, description, ref thisobj); //i was surprised you had to pass it by reference

//if you want to remove the balloon which you have drawn without redrawing the entire screen: 

mapControl.Refresh(esriViewDrawPhase.esriViewForeground, Type.Missing, Type.Missing); 

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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