Missing/Empty MapURI

810
3
08-10-2020 06:00 PM
Justin_ODell
New Contributor III

I noticed some quirky behavior with getting the MapURI out of certain panes.  I'm using ArcGIS Pro 2.2.4.
Based on https://community.esri.com/message/911800-activemapviewchanged-event-fires-twice#comment-914434, I was getting the related Map's URI from an attribute table pane.

...
ActivePaneChangedEvent.Subscribe(OnActivePaneChanged);
...

private void OnActivePaneChanged(PaneEventArgs args)
{
    var inPane = args.IncomingPane as TOCActiveMapViewProviderPane; 
    var inURI = inPane?.MapURI;
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

When initially loaded, sometimes inPane?.MapURI is empty ("") even when inPane is not null. Later in the same program, it may return the correct value.  The little experimentation I've done so far, shows having a "(" in the FeatureLayer's alias seemed to lead to the empty initial MapURI value.

1) Has anyone else seen this?

2) Are there any more details on when this should and shouldn't work? or how to work around it?

Thanks much!

possibly related to this note from: 
https://community.esri.com/message/875696-re-drag-drop-into-a-dockpane?commentID=875696#comment-8756... 

//last, get the source map to which the map members belong
var mapuri = dropInfo.GetMapUri();
//99 times out of a 100 this will be the active view map....
//but, if not, get the actual map (or scene) this way
var map = FrameworkApplication.Panes.OfType<IMapPane>()?.Select(mp => mp.MapView.Map)
              .Where(m => m.URI == mapuri).First();
0 Kudos
3 Replies
UmaHarano
Esri Regular Contributor

Hi Justin,

Are you specifically trying to find the Map URI when you open an Attribute table of a feature layer in the active map?

Just trying to understand your exact workflow.

Thanks!

Uma

0 Kudos
Justin_ODell
New Contributor III

Thanks for following up Uma!

My workflow goal is to react to an event when the active map changes to a different map (as opposed to changes to another pane that represents the same map -- e.g. clicking on an Attribute Table). This roughly corresponds to knowing when the values in the Contents pane change

Some examples of when I'd like to react:

On Map A, Click Map B -- raises event

On Map A, Click an Attribute Table from A -- no event

On Map A, Click an Attribute Table from B -- raises event

On Attribute Table from A, Click Map A -- no event

On Attribute Table from A, Click Attribute Table from B -- raises event

On Map A, Click Catalog pane -- no event (because no active map)

This would ideally apply to all panes that have an active map, including Layouts, Fields, etc. 

Originally I was using ActiveMapViewChangedEvent, but (similar to the issue linked above), I was getting too many events, when switching to attribute tables (first to null, then to the new map).  For a while I was handling ActivePaneChangedEvent, and extracting the Map URI separately depending on what type of pane it was.  Unfortunately the Map doesn't always exist at the time of Pane changed.  As a result, I switched back to ActiveMapViewChanged, but added a class-level variable to track to last non-empty URI.  Now, I'm able to raise the different-map event when the incoming IncomingView's Map's URI is different than the last non-empty URI.

 

private void OnActiveMapViewChanged(ActiveMapViewChangedEventArgs args)
{
    var inURI = args.IncomingView?.Map?.URI;
    if (!string.IsNullOrWhiteSpace(inURI) && string.Compare(_lastUri, inURI, true) != 0)
        // Raise my different-map event
    if (!string.IsNullOrWhiteSpace(inURI)) _lastUri = inURI;‍‍‍‍‍‍
}‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍

 

Which is working somewhat better, but still seems to have a few inconsistencies.

 

Is this a good approach? Do you have any other recommendations?

Thanks again!

0 Kudos
UmaHarano
Esri Regular Contributor

Hi Justin,

I am also seeing that the MapURI property is empty in the ActivePaneChangedEvent handler.  This is happening because this event is triggered before the Table pane (in your case) has been initialized (which is when the MapURI will exist).

To account for this, I subscribed to the ActivePaneInitializedEvent when the MapURI was empty - This seems to do the trick. I get a valid MapURI at this point. Code snippet below.

But - you could also simply only use the ActivePaneInitializedEvent. Based on your workflow (comparing the Map URIs to know if it is a completely new map), just this one event might give you all you need. 

Thanks

Uma

//Somewhere subscribe to ActivePaneChangedEvent

ArcGIS.Desktop.Framework.Events.ActivePaneChangedEvent.Subscribe(OnActivePaneChanged);

private void OnActivePaneInitialized(ActivePaneInitializedEventArgs args)
    {
      System.Diagnostics.Debug.WriteLine("Pane initialized");
      var activePane = FrameworkApplication.Panes.ActivePane as TOCActiveMapViewProviderPane;
      if (activePane == null) return;
      _mapURI = activePane.MapURI;
      System.Diagnostics.Debug.WriteLine($@"mapURI: {_mapURI}");      
    }

    private void OnActivePaneChanged(PaneEventArgs args)
    {
      if (args.IncomingPane == null) return;
      var inPane = args.IncomingPane as TOCActiveMapViewProviderPane;
      //var mapViewURI = inPane?.MapView?.Map.URI;//empty string
      _mapURI = inPane?.MapURI; //empty string    
      if (string.IsNullOrEmpty(_mapURI))
      {
        ActivePaneInitializedEvent.Subscribe(OnActivePaneInitialized);
        return;
      }       
      System.Diagnostics.Debug.WriteLine($"Debug Message. GetTypeName: {args.IncomingPane.GetType().Name}");
      System.Diagnostics.Debug.WriteLine($@"mapURI: {_mapURI}");
    }‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍‍