Select to view content in your preferred language

Track user added layers

1350
8
07-06-2010 05:35 AM
CarlosPiccirillo
Emerging Contributor
Hi everyone,

We have a custom toolbar with lots of forms to make loading enterprise wide data more user friendly, especially for non-GIS staff. From time to time we send out surverys asking the users if there are additional data sets they wish added to our forms. Since few people return the surveys, we thought a better way of tracking this is to see what data users are adding themselves through the Add Data button on the Standard toolbar.

My first attempt, was to create an extension and listen for the IActiveViewEvents::ItemAdded event. This works great but I get layers recorded that I do not want to track. We have predefined load sets which contain all the most common layers used by a particular group of users. Right now we have about a dozen different load sets. I already know which layers are in these load sets so I do not need to track them but IActiveViewEvents::ItemAdded tracks everything.

My second attempt was to use a customization filter to trap when the Add Data button is pressed and again this works great. However, as others have pointed out in previous posts, you cannot get anything in return from a built-in command so while I can detect the user pressing the Add Data button, I have no way of detecting what they added.

I thought about creating my own Add Data button but cannot figure out how to remove the built-in Add Data button and replace it with my own. Plus this seems like overkill.

Does anyone have an idea how to best get around this problem?

I could stick with IActiveViewEvents::ItemAdded and just ignore the layers from the load sets but was hoping for something more efficient as I suspect running queries to see if I layer has already been loaded would slow down the whole code and since the code has to run through Citrix, performance is a big issue.

Thanks,
Carlos
0 Kudos
8 Replies
JamesCrandall
MVP Alum
This may not be the best idea, or even if it's feasible, but how about taking advantage of the default behavior of the "Add Data" Command/button? 

What I mean is that, and this may or may not be correct, but I think that particular command always adds the layer as the first one in the TOC.  Can you not use this to track the layer the user just added by getting the first layer in the TOC after the AddData command is run?

pLayer = pMap.Layer(0)



But what if the user drags-and-drops a layer from ArcCatalog?  They may or may not drop it in the first position in the TOC.
0 Kudos
CarlosPiccirillo
Emerging Contributor
James,

Thanks for the reply. Unfortunately, it is not working correctly. The code in the customization filter detects when the Add Data button is pressed and then immediately executes your line of code before the user even adds anything to the TOC.

    if (pCommandItem.Name.ToString() == "File_AddData")
    {
 MessageBox.Show("Add Command Executed");

 IApplication pApplication = ClsHelper.GetArcGISApplication();
 IMxDocument pMxDocument = (IMxDocument)pApplication.Document;
 IMap pMap = pMxDocument.FocusMap;
 IFeatureLayer pFeatureLayer = pMap.get_Layer(0) as IFeatureLayer;
 MessageBox.Show("Layer name: " + pFeatureLayer.FeatureClass.AliasName);
    }
0 Kudos
KirkKuykendall
Deactivated User
Since you are doing this as a survey, it seems like you could have a service running in the background that periodically checks to see if arcmap is running and if so, scan to see what layers the user has in the TOC.  The service would be a standalone exe, that uses IAppROT to find arcmap instances, then IDocumentDatasets to list the datasource of each layer in the document to a log file.
0 Kudos
CarlosPiccirillo
Emerging Contributor
Thanks for the reply Kirk.

I like your idea but I do not think our IT department will go for it. They are already very unhappy that we are creating an extension in addition to a custom toolbar so I seriously doubt they are going to let us run a service in the background on their Citrix server. Whatever solution I end up using, it has to be contained within my extension or .dll file.

Ideally, the logic my boss wants to see is:

Track anything the user adds from the Add Data button that is on an Enterprise server (not local data), write this to an Access or Oracle table and keep a running total of how many times each particular data set is loaded so we can detect the most popular ones for inclusion on the forms.

I thought about adding a timer so that I can fire code to see what is in the TOC say every 5 minutes but I strongly suspect this would adversely affect performance as this was the case once before when I tried using timers through Citrix.
0 Kudos
JamesCrandall
MVP Alum
Carlos,

This works for me in my class that implements ICommand/IToolControl...  Also, it works if the user clicks the Add Data button or drops a layer into the TOC from ArcCatalog.



Public Class BFETools
Implements ESRI.ArcGIS.SystemUI.ICommand
Implements ESRI.ArcGIS.SystemUI.IToolControl
Private m_pApp As IApplication
Private WithEvents m_pActiveViewEvents As ESRI.ArcGIS.Carto.Map

'as normally, you will set your IApplication in your OnCreate Sub

Private Sub m_pActiveViewEvents_ItemAdded(ByVal Item As Object) Handles m_pActiveViewEvents.ItemAdded
        Dim pMxDoc As IMxDocument = m_pApp.Document
        Dim pLayer As IFeatureLayer
        pLayer = pMxDoc.FocusMap.Layer(0)

        MsgBox(pLayer.Name & " has been Added")
    End Sub
0 Kudos
KirkKuykendall
Deactivated User
Keep in mind a document can have more than one map,.

An IExtension could listen for newly added mapframes and initialize a new layer listener when a new map is added.  The extension could manage a list of listeners (one for each map in the document).  Or it might be easier to just put it in the MapFrames's IElementProperties.CustomProperty, but I'd test to make sure objects are destroyed gracefully when mapframes are deleted.

http://forums.esri.com/Thread.asp?c=93&f=993&t=246221&mc=2#752174
0 Kudos
CarlosPiccirillo
Emerging Contributor
Thanks James,

This is pretty much the code I currently have in my extension. Looks like this will be my best option to catch something being added regardless of the source, Add Data, ArcCatalog, etc.


Carlos,

This works for me in my class that implements ICommand/IToolControl...  Also, it works if the user clicks the Add Data button or drops a layer into the TOC from ArcCatalog.



Public Class BFETools
Implements ESRI.ArcGIS.SystemUI.ICommand
Implements ESRI.ArcGIS.SystemUI.IToolControl
Private m_pApp As IApplication
Private WithEvents m_pActiveViewEvents As ESRI.ArcGIS.Carto.Map

'as normally, you will set your IApplication in your OnCreate Sub

Private Sub m_pActiveViewEvents_ItemAdded(ByVal Item As Object) Handles m_pActiveViewEvents.ItemAdded
        Dim pMxDoc As IMxDocument = m_pApp.Document
        Dim pLayer As IFeatureLayer
        pLayer = pMxDoc.FocusMap.Layer(0)

        MsgBox(pLayer.Name & " has been Added")
    End Sub
0 Kudos
CarlosPiccirillo
Emerging Contributor
I had not considered the possibility that the user might add additional frames. I've never used a MapFrames's IElementProperties.CustomProperty so I will see if I can get that working. Thanks again!

Keep in mind a document can have more than one map,.

An IExtension could listen for newly added mapframes and initialize a new layer listener when a new map is added.  The extension could manage a list of listeners (one for each map in the document).  Or it might be easier to just put it in the MapFrames's IElementProperties.CustomProperty, but I'd test to make sure objects are destroyed gracefully when mapframes are deleted.

http://forums.esri.com/Thread.asp?c=93&f=993&t=246221&mc=2#752174
0 Kudos