Select to view content in your preferred language

ArcObjects TextBox on Map Document

6470
20
04-07-2014 11:28 AM
JamariPowers
Deactivated User
ArcMap 10.0
Arc Objects
Visual Studio 2010

I am new to using ArcObjects and have been getting more and more familiar with ArcMap. I am using Visual Studio and been having trouble creating / placing a simple textbox on an mxd. I am working in C#. I have a toolbar with buttons and hope to accomplish this on button click. The text box should be able to support text inside it as well.

Trying to start off small and work my way up. Any help on this topic would be greatly appreciated. Thanks in advance.
0 Kudos
20 Replies
LeoDonahue
Deactivated User
Well, thanks.

On the MSDN site, you can see the difference between using:  is and typeof to compare types.

http://msdn.microsoft.com/en-us/library/scekt9xw.aspx
0 Kudos
JamariPowers
Deactivated User
I am now working within a form. I've added a button to the form. I'm having trouble adding the 'ITextElement' to the mxd from clicking the button on the form. Is that possible?

My code snippet is below. Please help, again!!

namespace MapDecorator
{
    public partial class Form1 : Form
    {

        private IElement _element;
        private IGlobeGraphicsElementProperties _elementProperties;

        public Form1()
        {
            InitializeComponent();
           
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            string[] files = System.IO.Directory.GetFiles(@"C:\This");

            this.comboBox1.Items.AddRange(files);
        }

        private void button1_Click(object sender, EventArgs e)
        {
            this.Close();
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
           
        }

        private void PlaceText_Click(object sender, EventArgs e)
        {
            ITextElement _textElement = new TextElementClass();
            _element = _textElement as IElement;
            ITextSymbol _textSymbol = new TextSymbolClass();
            _textElement.Text = "Test me";

            this._element = new TextElementClass();
           
        }
    }
}

Thanks in advance
0 Kudos
LeoDonahue
Deactivated User
If you can wait long enough, ESRI will implement a form designer that lets non-programmers wire up GUI events to things like this.
0 Kudos
JamariPowers
Deactivated User
eehhhh...I kinda need a solution to this asap. lol
0 Kudos
LeoDonahue
Deactivated User
It is possible.

You add TextElements to a GraphicsContainer, which requires an ActiveView.  Once you add the element of your choice to the GraphicsContainer, you refresh your ActiveView.  TextElements also require that you set their text symbol and geometry so that they know where to go in the map.

If you want to do this from an IDE generated form and button, and not from an ESRI Add-In generated button, then you will need to find a way to get instances of your mxdocument from within your Form's instance.

Your most recent code sample is very sparse and is missing alot of this.

Try building a sample form with a button that when clicked returns properties of the mxdocument, such as the name or path of the document.  Once you can do that, then building a TextElement and its dependencies and adding that to the Graphics Container will be easy.

Hint: if this "is" an Add-in project, then create a Button Add-in that launches your Form.
0 Kudos
JamariPowers
Deactivated User
oooo000 I see....Ok. I'm beginning to get a better understanding of what needs to be done. Those ArcObjects sites don't explain things in dumb-downed terms for users who have never really used arcObjects (i.e. me).

Thanks again. I now have somewhat of a pseudo-coded plan of attack.
0 Kudos
LeoDonahue
Deactivated User
Take this thread with a grain of salt, as there is no standard way of implementing this.

http://forums.arcgis.com/threads/101002-C-MVC-Add-in-pattern
0 Kudos
JamariPowers
Deactivated User
So I think it's starting to come around. I was able to add a "box" to an mxd document. It was more so a legend but its a start. My code is below:

protected override void OnClick()
        {

            IMxDocument _mxDoc = ArcMap.Application.Document as IMxDocument;
            IMap _map = _mxDoc.FocusMap;

            IActiveView _activeView = _mxDoc.ActiveView;
           // IActiveView _activeView = _map as IActiveView;
            IPageLayout3 _pageLayout = _activeView as IPageLayout3;

            Double posX = 2.0;
            Double posY = 2.0;
            Double legW = 5.0;


            IGraphicsContainer _GraphContain = _pageLayout as IGraphicsContainer;
            IMapFrame _mapFrame = _GraphContain.FindFrame(_map) as IMapFrame;
            ESRI.ArcGIS.esriSystem.UID _uid = new UIDClass();
            _uid.Value = "esriCarto.Legend";
            IMapSurroundFrame _mapSurroundFrame = _mapFrame.CreateSurroundFrame((ESRI.ArcGIS.esriSystem.UID)_uid, null);
            
            IQuerySize _querySize = _mapSurroundFrame.MapSurround as IQuerySize;
            Double w = 0;
            Double h = 0;
            _querySize.QuerySize(ref w, ref h);
            Double aspectRatio = w / h;


            IEnvelope _envelope = new EnvelopeClass();
            _envelope.PutCoords(posX, posY, (posX * legW), (posY * legW / aspectRatio));
            IElement _element = _mapSurroundFrame as IElement;
            _element.Geometry = _envelope;
            _GraphContain.AddElement(_element, 0);

            _activeView = _mxDoc.ActiveView;

            if (_activeView is IPageLayout)
            
            {
                MessageBox.Show("You're in layout view");
            }
            else if (_activeView is IMap)
            {
                MessageBox.Show("You're in Data view");
                
            }
          
            _activeView.Refresh();

        }


I'm thinking I need to add a TextElement, as well as TextElement properties to the Graphics Container instead of just element properties. It is all grouped together with no real structure, but its a work in progress. What do you think?
0 Kudos
LeoDonahue
Deactivated User
Review this.  I think this is what you are after, except the group element.

import java.awt.event.MouseEvent;
import java.io.IOException;
import java.text.DecimalFormat;

import com.esri.arcgis.addins.desktop.Tool;
import com.esri.arcgis.arcmapui.IMxDocument;
import com.esri.arcgis.carto.GroupElement;
import com.esri.arcgis.carto.IActiveView;
import com.esri.arcgis.carto.IGraphicsContainer;
import com.esri.arcgis.carto.MarkerElement;
import com.esri.arcgis.carto.TextElement;
import com.esri.arcgis.display.IDisplayTransformation;
import com.esri.arcgis.display.IScreenDisplay;
import com.esri.arcgis.display.ITextSymbol;
import com.esri.arcgis.display.RgbColor;
import com.esri.arcgis.display.SimpleMarkerSymbol;
import com.esri.arcgis.display.TextSymbol;
import com.esri.arcgis.display.esriTextVerticalAlignment;
import com.esri.arcgis.framework.IApplication;
import com.esri.arcgis.geometry.IPoint;
import com.esri.arcgis.geometry.ISpatialReference;
import com.esri.arcgis.geometry.Point;
import com.esri.arcgis.geometry.SpatialReferenceEnvironment;
import com.esri.arcgis.interop.AutomationException;
import com.esri.arcgis.support.ms.stdole.StdFont;


public class Tool1 extends Tool {
    
    private IApplication app;
    private IActiveView av;
    private IMxDocument mxDocument;
    
    private String message;
    
    @Override
    public void activate() throws IOException, AutomationException {
        
    }

    @Override
    public void init(IApplication arg0) throws IOException, AutomationException {
        super.init(arg0);
        this.app = arg0;
        mxDocument = (IMxDocument) app.getDocument();
        av = mxDocument.getActiveView();
        
    }

    @Override
    public void mousePressed(MouseEvent mouseEvent) {
        super.mousePressed(mouseEvent);
        try{
            Point point1 = new Point();  // point where user clicks
            point1.putCoords((double)mouseEvent.getX(), (double)mouseEvent.getY());
            
            Point point2 = (Point) getMapCoordinatesFromScreenCoordinates(point1,av);
            double x = point2.getX();
            double y = point2.getY();
            DecimalFormat df = new DecimalFormat("#.####");
            message = "x: " + df.format(x) + " y: " + df.format(y);
            
            RgbColor color = new RgbColor();
            color.setRed(255);
            
            StdFont font = new StdFont();
            font.setName("Arial");
            
            SimpleMarkerSymbol sms = new SimpleMarkerSymbol();
            sms.setStyle(com.esri.arcgis.display.esriSimpleMarkerStyle.esriSMSCircle);
            sms.setColor(color);
            
            MarkerElement me = new MarkerElement();
            me.setSymbol(sms);
            me.setGeometry(point2);
            me.setName("me");
            
            ITextSymbol textSymbol = new TextSymbol();
            textSymbol.setColor(color);
            textSymbol.setFont(font);
            textSymbol.setSize(9);
            textSymbol.setVerticalAlignment(esriTextVerticalAlignment.esriTVACenter);
            
            TextElement textElement = new TextElement();
            textElement.setSymbol(textSymbol);
            textElement.setColor(color);
            textElement.setText(message);
            textElement.setGeometry(point2);
            textElement.setYOffset(11.27);
            textElement.setName("textElement");
            
            GroupElement gp = new GroupElement();
            gp.addElement(textElement);
            gp.addElement(me);
            gp.setName("click location");
            
            IGraphicsContainer graphicsContainer = av.getGraphicsContainer();
            graphicsContainer.addElement(gp, 0);
            av.partialRefresh(com.esri.arcgis.carto.esriViewDrawPhase.esriViewGraphics, gp, av.getExtent());
            
        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    public IPoint getMapCoordinatesFromScreenCoordinates(IPoint screenPoint, IActiveView activeView)throws Exception{

        if (screenPoint == null || screenPoint.isEmpty() || activeView == null)
            return null;
        
        IScreenDisplay screenDisplay = activeView.getScreenDisplay();
        IDisplayTransformation displayTransformation = screenDisplay.getDisplayTransformation();

        return displayTransformation.toMapPoint((int)screenPoint.getX(), (int)
            screenPoint.getY());
    }

}


[ATTACH=CONFIG]33310[/ATTACH]
0 Kudos
JamariPowers
Deactivated User
I appreciate your code snippet, but I still have no real understanding of all the misc other function calls (SimpleMarkerSymbol, MarkerElement, etc). I can look up their meaning but do not understand really why they are needed or why they should/would be needed. Like I said, I'm trying to understand and learn and create all from scratch. Code without explanation in my context won't really help

And because I am using C# and don't exaclty know of all the references needed to import, it makes it a tad bit more challenging. Thanks for the post though.
0 Kudos