Confused about adding a tool to a form in an Add-in

3124
6
03-27-2012 11:24 AM
SteveCole
Frequent Contributor
I have some experience already with add-ins, namely add-ins which are collections of very specific tools or buttons for use in Arcmap. For my current project, I'm developing an add-in which our staff can use to attribute and geotag JPEG photos taken while in the field. I have a windows form which has several text boxes for the user to input information. I have a UICommand in my add-in which displays the form and all that works great. What I want to add to do is add a button to that form which is used to click on the map, get x,y coordinates, and then populate them back into a textbox on the windows form.

This is where I'm stuck and it seems to me like this is a gap in the documentation.

How do I add a UITool to a windows form within my VB.NET project? Does the tool have to be already developed (or compiled) or can I have it in my current project?
I'd really like to keep it as a windows form instead of a dockable window since I'm using the form to display JPEGs in a sort of slideshow presentation. Funny thing is, I thought the EXIF updating would be the hardest part but I've now got that working. I just need this tiny bit!

As I eluded to, I'm using Visual Studio Express 2008 VB.NET as my development environment and version10 for ArcGIS.

Thanks!

Steve
0 Kudos
6 Replies
SteveCole
Frequent Contributor
Think I'm on the right path. I hate it when I search the forum, find nothing, post a question, and THEN find something useful in a forum search!

Anyways, Neil Clemmons provided a rough guide in this thread:

http://forums.arcgis.com/threads/50996-Create-Point-on-screen-Trigger-mousedown-via-form?highlight=a...

And this thread gives you the code to "activate" your add-in tool:

http://forums.arcgis.com/threads/31897-Activate-Add-In-Tool?highlight=add+tool+form

Be sure that your add-in has been compiled or the tool won't appear in the list returned by My.ThisAddIn.IDs. So far the tool activates and the mouse click on the map returns coordinates so I'm most of the way there!..
0 Kudos
LeoDonahue
Occasional Contributor III
I have a UICommand in my add-in which displays the form and all that works great. What I want to add to do is add a button to that form which is used to click on the map, get x,y coordinates, and then populate them back into a textbox on the windows form


I don't think the "add-in" environment will allow you to place Tools wherever you want.  Although I haven't tried it, an add-in tool is just a class that extends Tool, so I guess you could create an instance of a Tool, but I don't know if ArcMap does anthing else besides just calling your Tool for you when it is located on an existing toolbar.

A Tool interacts with the map, in the sense of being able to click in the map and get information.  You *could* design the application so that when the user clicks on a tool, the tool would get the click point on the map, then launch the form, thereby populating the form with that click point information.  This is similar to how the "Identify" tool already works.

When I think about how an edit session works, I start by clicking on a tool and then doing something in the map, then doing something in a (attribute) form window.  Sure, it looks like you are launching a tool from a dockable window, when you click a construction tool template, but those aren't add-ins.
0 Kudos
SteveCole
Frequent Contributor
Hi Leo,

I don't know if it's supposed to or not, but I can tell you that it *IS* working! It might be a bit of trickery since the "tool" button on the form is really just a simple form button. As the first link suggests, the click event for the form button really just changes the active tool to my custom UITool. Inside the OnMouseDown event for the UITool, I get my coordinates and then transfer the values back to my form in this manner-

Dim theForm As frmPhotoDlg 'My custom form's class name
theForm = System.Windows.Forms.Application.OpenForms(0)
theForm.txtLatitude.Text = pPoint.Y
theForm.txtLongitude.Text = pPoint.X


So far, it all works just fine. I should point out that for the time being, I'm not editing any data. I'm merely using Arcmap to draw our data and to extract the geolocation information. The Arcmap related portion of my current add-in is only about 5%. I may expand things to include writing records into a database table in the future. Not really sure which direction this tool will be heading.

Here's also a screenshot of Arcmap plus the open form from my Add-in..
[ATTACH=CONFIG]13054[/ATTACH]
0 Kudos
LeoDonahue
Occasional Contributor III

Dim theForm As frmPhotoDlg 'My custom form's class name
theForm = System.Windows.Forms.Application.OpenForms(0)



So do you now have two variables that can manipulate your Form?  "theForm" and whatever other variable you used to show the form?
0 Kudos
SteveCole
Frequent Contributor
I'm not exactly sure what you're asking. I think I only have the one (theForm). I'm still a bit green with VB.NET to answer authoritatively!

The code snippit I had provided all comes from the same Sub procedure (OnMouseDown for my Add-in component). The full sub code would be this:

Protected Overrides Sub OnMouseDown(ByVal arg As ESRI.ArcGIS.Desktop.AddIns.Tool.MouseEventArgs)
        MyBase.OnMouseDown(arg)
        Dim application As ESRI.ArcGIS.Framework.IApplication
        Dim pMxDoc As ESRI.ArcGIS.ArcMapUI.IMxDocument
        Dim pPoint As ESRI.ArcGIS.Geometry.IPoint
        Dim pClone As ESRI.ArcGIS.esriSystem.IClone
        Dim pGeometry As ESRI.ArcGIS.Geometry.IGeometry
        Dim pSpatialRefFactory As ESRI.ArcGIS.Geometry.ISpatialReferenceFactory
        Dim pSpatialRef As ESRI.ArcGIS.Geometry.ISpatialReference
        Dim pGeographicCoordSys As ESRI.ArcGIS.Geometry.IGeographicCoordinateSystem
        Dim pProjectedCoordSys As ESRI.ArcGIS.Geometry.IProjectedCoordinateSystem
        Dim theForm As frmPhotoDlg
        Dim theResults As String

        Try
            'Get the point where the user clicked
            application = My.ArcMap.Application
            Dim document As ESRI.ArcGIS.Framework.IDocument = application.Document
            pMxDoc = CType(document, ESRI.ArcGIS.ArcMapUI.IMxDocument)
            If pMxDoc.CurrentLocation.IsEmpty Then Exit Sub
            'Clone the point because we don't want to alter
            'the actual document's current location point
            pClone = pMxDoc.CurrentLocation
            pPoint = pClone.Clone
            pGeometry = pPoint

            'Create a new geographic coordinate system to use in the conversion
            pSpatialRefFactory = New ESRI.ArcGIS.Geometry.SpatialReferenceEnvironment
            pGeographicCoordSys = pSpatialRefFactory.CreateGeographicCoordinateSystem(ESRI.ArcGIS.Geometry.esriSRGeoCSType.esriSRGeoCS_NAD1983)
            pSpatialRef = pGeographicCoordSys 'QI
            pSpatialRef.SetFalseOriginAndUnits(-180, -90, 1000000)

            pGeometry.Project(pSpatialRef)

            Dim theDegrees As Double
            Dim theMinutes As Double
            Dim theSeconds As Double

            Dim longDms As String
            Dim latDms As String
            Dim longDD As Double
            Dim latDD As Double

            longDD = Math.Abs(pPoint.X)
            latDD = pPoint.Y

            theDegrees = Int(longDD)
            theMinutes = (longDD - theDegrees) * 60
            theSeconds = Int((theMinutes - Int(theMinutes)) * 60)

            longDms = theDegrees & "° " & Int(theMinutes) & "' " & theSeconds & Chr(34)

            theDegrees = Int(latDD)
            theMinutes = (latDD - theDegrees) * 60
            theSeconds = Int((theMinutes - Int(theMinutes)) * 60)

            latDms = theDegrees & "° " & Int(theMinutes) & "' " & theSeconds & Chr(34)

            theResults = "DECIMAL DEGREES:" & vbNewLine & vbNewLine & vbTab & "Latitude: " & pPoint.Y & vbNewLine
            theResults = theResults & vbTab & "Longitude: " & pPoint.X & vbNewLine & vbNewLine & "DEGREES/MINUTES/SECONDS:"
            theResults = theResults & vbNewLine & vbNewLine & vbTab & "Latitude: " & latDms & vbNewLine & vbTab & "Longitude: " & longDms

            'My.Computer.Clipboard.SetText(theResults)

            theForm = System.Windows.Forms.Application.OpenForms(0)
            theForm.txtLatitude.Text = pPoint.Y
            theForm.txtLongitude.Text = pPoint.X

            'MsgBox(theResults, vbInformation, "Geographic Results")

            pSpatialRefFactory = Nothing
            pGeographicCoordSys = Nothing
            pProjectedCoordSys = Nothing
            pSpatialRef = Nothing
            pClone = Nothing
            pPoint = Nothing
            pGeometry = Nothing
            pMxDoc = Nothing
            application = Nothing
            document = Nothing
        Catch ex As Exception
            globalErrorHandler(ex)
        End Try
    End Sub
0 Kudos
LeoDonahue
Occasional Contributor III
I'm still a bit green with VB.NET...

May I suggest the StringBuilder class for you then?

http://support.microsoft.com/kb/306821
0 Kudos