4

I'm developing arcgis add-in tools. I now want the map display to zoom to the geometry and then flash it.

I did this by defining two methods:

 public static void ZoomToGeometry(IGeometry geometry, IActiveView activeView)
    {
        IEnvelope env = geometry.Envelope;
        IGeometry5 geo = geometry as IGeometry5;

        if (env.Width == 0 || env.Height == 0)
        {
            IPoint centerPoint = new PointClass();
            centerPoint.X = geo.CentroidEx.X;
            centerPoint.Y = geo.CentroidEx.Y;

            //IDisplayTransformation displayTrans = activeView.ScreenDisplay.DisplayTransformation;
            //displayTrans.SpatialReference = activeView.FocusMap.SpatialReference;

            env.XMin = centerPoint.X - 0.001;
            env.XMax = centerPoint.X + 0.001;
            env.YMin = centerPoint.Y - 0.001;
            env.YMax = centerPoint.Y + 0.001;

            env.CenterAt(centerPoint);
        }
        env.Expand(0.5, 0.5, true);
        activeView.Extent = env;
        activeView.Refresh();
    }

and the flash geometry function borrowed from arcgis snippets:

public static void FlashGeometry(IGeometry geometry, IRgbColor color, IDisplay display, System.Int32 delay)
    {
        if (geometry == null || color == null || display == null)
        {
            return;
        }

        display.StartDrawing(display.hDC, (System.Int16)esriScreenCache.esriNoScreenCache); // Explicit Cast

        switch (geometry.GeometryType)
        {
            case esriGeometryType.esriGeometryPolygon:
                {
                    //Set the flash geometry's symbol.
                    ISimpleFillSymbol simpleFillSymbol = new SimpleFillSymbolClass();
                    simpleFillSymbol.Color = color;
                    ISymbol symbol = simpleFillSymbol as ISymbol; // Dynamic Cast
                    symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;

                    //Flash the input polygon geometry.
                    display.SetSymbol(symbol);
                    display.DrawPolygon(geometry);
                    System.Threading.Thread.Sleep(delay);
                    display.DrawPolygon(geometry);
                    break;
                }

            case esriGeometryType.esriGeometryPolyline:
                {
                    //Set the flash geometry's symbol.
                    ISimpleLineSymbol simpleLineSymbol = new SimpleLineSymbolClass();
                    simpleLineSymbol.Width = 4;
                    simpleLineSymbol.Color = color;
                    ISymbol symbol = simpleLineSymbol as ISymbol; // Dynamic Cast
                    symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;

                    //Flash the input polyline geometry.
                    display.SetSymbol(symbol);
                    display.DrawPolyline(geometry);
                    System.Threading.Thread.Sleep(delay);
                    display.DrawPolyline(geometry);
                    break;
                }

            case esriGeometryType.esriGeometryPoint:
                {
                    //Set the flash geometry's symbol.
                    ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbolClass();
                    simpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
                    simpleMarkerSymbol.Size = 12;
                    simpleMarkerSymbol.Color = color;
                    ISymbol symbol = simpleMarkerSymbol as ISymbol; // Dynamic Cast
                    symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;

                    //Flash the input point geometry.
                    display.SetSymbol(symbol);
                    display.DrawPoint(geometry);
                    System.Threading.Thread.Sleep(delay);
                    display.DrawPoint(geometry);
                    break;
                }

            case esriGeometryType.esriGeometryMultipoint:
                {
                    //Set the flash geometry's symbol.
                    ISimpleMarkerSymbol simpleMarkerSymbol = new SimpleMarkerSymbolClass();
                    simpleMarkerSymbol.Style = esriSimpleMarkerStyle.esriSMSCircle;
                    simpleMarkerSymbol.Size = 12;
                    simpleMarkerSymbol.Color = color;
                    ISymbol symbol = simpleMarkerSymbol as ISymbol; // Dynamic Cast
                    symbol.ROP2 = esriRasterOpCode.esriROPNotXOrPen;

                    //Flash the input multipoint geometry.
                    display.SetSymbol(symbol);
                    display.DrawMultipoint(geometry);
                    System.Threading.Thread.Sleep(delay);
                    display.DrawMultipoint(geometry);
                    break;
                }
        }
        display.FinishDrawing();
    }

However, when I use these code like this:

ZoomToGeometry(m_interPointList[e.RowIndex] as IGeometry, m_activeView);
        FlashGeometry(m_interPointList[e.RowIndex] as IGeometry, 
            CommonFunctions.GetColorByRGBValue(255, 0, 0) as IRgbColor, m_activeView.ScreenDisplay, 100);

the ArcMap will first flash that geometry on the screen, and then zoom to the geometry. This is the wrong order, I want it first zoom to the geometry, then flash...

I've tried many ways, I can't solve this problem. Hope someone can help?

3
  • I think the problem is that activeView.Refresh() just invalidates screen rectangle, but doesn't start redraw immediately. Try to call activeView.ScreenDisplay.UpdateWindow() just after Refresh(). Another thing: there is a default flash implementation in ArcMap: IApplication.Flash(IGeometry). Commented Apr 5, 2017 at 7:05
  • Thanks, activeView().ScreenDisplay.UpdateWindow() works, but I don't find the IApplication.Flash(IGeometry) in API document. I'm using 10.2 version.
    – Jacory Gao
    Commented Apr 5, 2017 at 8:05
  • Yes, you're right. I meant HookHelper, added links in the answer. Commented Apr 5, 2017 at 8:26

1 Answer 1

3

The problem is that activeView.Refresh() just invalidates screen rectangle, but doesn't start redraw immediately. Try to call activeView.ScreenDisplay.UpdateWindow() just after Refresh().

BTW, there is a ESRI.ArcGIS.Controls.HookHelperClass that can be used for zooming and flashing.

Examples: hookActionsZoom, hookActionsFlash.

0

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.