Find element / graphic in layout view by name and move

4276
9
01-04-2012 10:13 PM
KeaganAllan
New Contributor III
Hi,

i am looking for a way to find a grpahic in my layout view by it's name and move it to a set of given page coordinates.

I basically have a series of graphics that I need to programmitcally move during the running of my script, each graphic needs to move at a specific moment.

I need to be able to find the graphic by its "Element Name", select it and then move it to a set of coordinates and then move it back again.

I am using VB Express and VB.Net to do this.
Any ideas?
I have been able to find small bits of script here and there but have yet to be able to get it to work.

Thank you!
0 Kudos
9 Replies
AlexanderGray
Occasional Contributor III
This is the code I use for that.  Just feed it the graphic container of the layout and the name you want.  This code won't search sub elements, if you have group elements and you want one of the element in the group, you will have to open it up loop through the sub elements and check the name.

Private Function GetElementInContainer(ByVal container As IGraphicsContainer, ByVal name As String) As IElement
    container.Reset()
    Dim elem As IElement = container.Next
    While elem IsNot Nothing
      Dim elemProps As IElementProperties = DirectCast(elem, IElementProperties)
      If String.Compare(elemProps.Name, name, True) = 0 Then
        Return elem
      End If
      elem = container.Next
    End While
    Return Nothing
  End Function
0 Kudos
KeaganAllan
New Contributor III
Hi Alex,

Thank you!
I am still relatively new to VB and writing add-ins, so I will fumble around with this and let you know how it goes.

Cheers,

K
0 Kudos
KeaganAllan
New Contributor III
Hi Alex,

I have been having issues trying to understand where your code fits into the whole process.
Would you happen to have an example / text I would be able to look at in order to see how this all fits together?

Thank you!
0 Kudos
AlexanderGray
Occasional Contributor III
Keagan,

This snippet was pulled from a large project that does many more things that does not demonstrate the function and that requires data to have a specific schema and requires specific elements to be in the layout.  I don't write add-ins, I write the old fashion ArcObjects components.

In this case, I used the function provided to find elements on the page layout from a command in ArcMap.  The process would be the same for finding graphic elements on an ArcMap map, an engine mapcontrol or any other graphic container.  The graphic container can be obtained by casting the map or layout to an IGraphics container.  The map or layout can be obtained from the IMxDocument.
As for moving the element, graphic elements implement the ITransform2d interface which has a move method.
Cheers
0 Kudos
KeaganAllan
New Contributor III
Awesome,

Thanks for explaining that, I am starting to get the hang of these things now.
I have the itreansfor2D code working, I was just having issues with the selection of the individual graphic elements.

I will see if I can get this to work for me.

Thanks again for your time!
Cheers,
K
0 Kudos
KeaganAllan
New Contributor III
Ok,

I have been playing around with this code and another I found online.
Currently this is not working and I was hoping someone could maybe point me in the right direction.

Below is my code, with some annotation as to what I think is going on (my very limited knowledge).

Public Sub MoveElements()
        Dim activeview As IActiveView
        Dim pageLayout As IPageLayout = New PageLayoutClass()
        Dim name As String
        Dim pmxdoc As IMxDocument
        pmxdoc = My.ArcMap.Document

        'Make pagelayout the active view
        pmxdoc.ActiveView = pmxdoc.PageLayout
        activeview = pmxdoc.ActiveView
        name = "1"
      

If TypeOf activeview Is IPageLayout Then
            pageLayout = TryCast(activeview, IPageLayout)
            Dim graphicsContainer As IGraphicsContainer = TryCast(pageLayout, IGraphicsContainer)

            graphicsContainer.Reset()

            Dim transform2D As ITransform2D
            Dim elem As IElement
            '''''''''''''''

          
            elem = GetElementInContainer(elem, name) 'So the way I see it here: I am setting up which of the graphics will be selected based on the "name" taken from the function


            'While Not elem Is Nothing
            transform2D = TryCast(elem, ITransform2D)
            transform2D.Move(10, 0)
            'elem = graphicsContainer.Next()
            'End While

        Else
            MessageBox.Show("This tool only works in pagelayout view.")
        End If

        'Refresh only the page layout's graphics.
        activeview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, Nothing, Nothing)
    End Sub

    Private Function GetElementInContainer(ByVal container As IGraphicsContainer, ByVal name As String) As IElement


        Dim graphicsContainer As IGraphicsContainer
        'graphicsContainer = TryCast(pagelayout, IGraphicsContainer)
        'Loop through all the elements and move each one inch.

        ' graphicsContainer.Reset()
        'container.Reset() ### I kept having a crash here, so I played around with the graphics container.

'####### It doesnt get passed here #####

        Dim elem As IElement
        'Dim elem As IGraphicElement = container.Next
        elem = graphicsContainer.Next

        While elem IsNot Nothing
            Dim elemProps As IElementProperties = DirectCast(elem, IElementProperties)
            If String.Compare(elemProps.Name, name, True) = 0 Then
                Return elem
            End If
            elem = graphicsContainer.Next
        End While
        Return Nothing
    End Function


Any ideas, recommendations are welcome!!

Thanks
K
0 Kudos
AlexanderGray
Occasional Contributor III
Looks like you are passing an element into the GetElementInContainer function.  That would force an implicit cast from IElement to IGraphicscontainer.  That cast is not valid.  You need to pass the graphicscontainer.  I would also suggest you turn on the option explicit and option strict in your project.  The option strict prevents implicit casts from being compiled.  In this case, the code would not compile. I find that helps me write cleaner code where I have to cast every thing to the right interface before using the variable.
0 Kudos
KeaganAllan
New Contributor III
Hi,

Thanks for all your help.
Whilst I wasnt able to use your initial Function to do what I would have liked.

I managed to use your advice as well as components of that function and get a solution.
This will find a graphic element in the page layout by name and move it by a user set amount (exactly what I wanted)

Thanks again and here is the code, in case someone ever needs it (I know I looked and couldnt find an example).

 Public Sub MoveElement()
        Dim activeview As IActiveView
        Dim pageLayout As IPageLayout = New PageLayoutClass()
        Dim name As String
        Dim pmxdoc As IMxDocument
        pmxdoc = My.ArcMap.Document

        'Make pagelayout the active view
        pmxdoc.ActiveView = pmxdoc.PageLayout
        activeview = pmxdoc.ActiveView
        name = "1"
        If TypeOf activeview Is IPageLayout Then
            pageLayout = TryCast(activeview, IPageLayout)

            Dim transform2D As ITransform2D
            Dim elem As IElement

            pmxdoc = My.ArcMap.Application.Document
            Dim pmap As IPageLayout
            Dim pMapGraphicsSelect As IGraphicsContainerSelect
           
            pmap = activeview

            '''''''''''''''
            Dim container As IGraphicsContainer = TryCast(pageLayout, IGraphicsContainer)
            container.Reset()
            elem = container.Next
            Do While elem IsNot Nothing
                pMapGraphicsSelect = TryCast(pageLayout, IGraphicsContainerSelect)
                Dim elemProps As IElementProperties = DirectCast(elem, IElementProperties)
                If String.Compare(elemProps.Name, name, True) = 0 Then
                    pMapGraphicsSelect.SelectElement(elem)
                    elem = pMapGraphicsSelect.SelectedElement(0)
                    Exit Do
                End If
                elem = container.Next()
            Loop

           
            transform2D = TryCast(elem, ITransform2D)
            transform2D.Move(10, 10)

        Else
            MessageBox.Show("This tool only works in pagelayout view.")
        End If

        'Refresh only the page layout's graphics.
        activeview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, Nothing, Nothing)
    End Sub
0 Kudos
KeaganAllan
New Contributor III
I just wanted to say thanks for all your assistance with regards to my scripting issue.
While I wasnt able to get your Function to work, I did manage to take your idea / thought process and apply it to my problem.

The code below will look for a graphic element in the page layout and move it to a point (based on set criteria - in this case "name = 1").
Reason I am using this code is I need to automatically move legends (converted into gfx because for some reason my ArcMap reformats the legends everytime!).
So if a particular layer is active, then that legend is moved into place, then ultimately moved out of the printable page area.

I will insert this code numerous times into my final code - with both positive and negative values to move it in and out of view.
Maybe it is not the most efficient code, it is (as far as I can tell) the only code online - hahaha weeks of searching - anyways.
Any comments / crits are always welcome, I am VERY new to this so have most likely not followed the correct method.

Public Sub MoveElements()
        Dim activeview As IActiveView
        Dim pageLayout As IPageLayout = New PageLayoutClass()
        Dim name As String
        Dim pmxdoc As IMxDocument
        pmxdoc = My.ArcMap.Document

        'Make pagelayout the active view
        pmxdoc.ActiveView = pmxdoc.PageLayout
        activeview = pmxdoc.ActiveView
        name = "1"
        If TypeOf activeview Is IPageLayout Then
            pageLayout = TryCast(activeview, IPageLayout)

            Dim transform2D As ITransform2D
            Dim elem As IElement

            pmxdoc = My.ArcMap.Application.Document
            Dim pmap As IPageLayout
            Dim pMapGraphicsSelect As IGraphicsContainerSelect
           
            pmap = activeview
            Dim i As Integer

            '''''''''''''''
            Dim container As IGraphicsContainer = TryCast(pageLayout, IGraphicsContainer)
            container.Reset()
            elem = container.Next
            pMapGraphicsSelect = TryCast(pageLayout, IGraphicsContainerSelect)
            pMapGraphicsSelect.SelectAllElements()

            Do Until i = pMapGraphicsSelect.ElementSelectionCount - 1 'While elem IsNot Nothing

                Dim elemProps As IElementProperties = DirectCast(elem, IElementProperties)

                'For i = 0 To pMapGraphicsSelect.ElementSelectionCount - 1

                If String.Compare(elemProps.Name, name, True) = 0 Then
                    pMapGraphicsSelect.SelectElement(elem)
                    elem = pMapGraphicsSelect.SelectedElement(i)
                    Exit Do
                End If
                'elem = container.Next()

                'Next i
                i = i + 1
            Loop

           
            transform2D = TryCast(elem, ITransform2D)
            transform2D.Move(10, 10)
            pMapGraphicsSelect.UnselectAllElements()
        Else
            MessageBox.Show("This tool only works in pagelayout view.")
        End If

        'Refresh only the page layout's graphics.
        activeview.PartialRefresh(esriViewDrawPhase.esriViewGraphics, Nothing, Nothing)
    End Sub
0 Kudos