Error-Object already owned for LayerCollection

521
4
Jump to solution
09-10-2019 07:54 PM
PrashantKirpan
Occasional Contributor

Hi All,

I am using WPF 100.5 runtime API with MVVM framework. I have integrated toolkit:LayerLegend control in separate user control which has his own view model.

I am passing Map.Operationlayers from MainMapVM to LegendVM and binding to public Layercollection property in usercontrol. This approach is working fine but i want to extract only specific layers and show in legend - this time it fails and throwing 'Object already Owned exception - from ARCGIS Runtime'

My sample code.

1MapControlViewModel 

public class MapControlViewModel : ViewModelBase
{

   public LayerListControlViewModel LayerlistControlVM { get; set; } = new LayerListControlViewModel();

   ..

   public void click()
      {

         //Passing operation layers to legend user control
          LayerlistControlVM.InitializeLayerListControl(Map.OperationalLayers); 
       }

}

----------------------------------------------------------------------------------------------------------------------------------------------------

2. LayerListControlViewModel 

public class LayerListControlViewModel : ViewModelBase
{
    public LayerCollection OperationalLayers { get; set; } = new LayerCollection();

    ..

    

    public void InitializeLayerListControl(LayerCollection layerColl)
         {

             OperationalLayers.Add(layerColl[0]); Exception on this line - 'Object already owned.: Already owned'

             //OperationalLayers = layerColl; Works well

            RaisePropertyChanged(() => OperationalLayers);

 

           }

}

----------------------------------------------------------------------------------------------------------------------------------------------------

2.1 LayerListControl.XAML

<ScrollViewer>
     <ItemsControl ItemsSource="{Binding OperationalLayers, Mode=OneWay}" Margin="10" >
          ....

          ....
      </ItemsControl>
</ScrollViewer>

----------------------------------------------------------------------------------------------------------------------------------------------------

I am not sure why i am getting exception while extracting data from Layercollection Object and assign to Public property with same class.

Any help would be appreciated.

Regards,

Prashant 

Reply
0 Kudos
1 Solution

Accepted Solutions
JoeHershman
MVP Regular Contributor

Yes, but the Layer object is in a different OperationalLayers collection.  It is not that you have created a new LayerCollection.  You have to remove the layer from the first map in order to add it to the new map.

This is a sample to how the basemap was switched out and the layers had to be removed and add anew 

private void ResetMapLayers(Map map)
{
LayerCollection operationalLayers = new LayerCollection();
Layer[] tempLayers = new Layer[_map.OperationalLayers.Count];
_map.OperationalLayers.CopyTo(tempLayers, 0);

foreach (var operationalLayer in tempLayers)
{
_map.OperationalLayers.Remove(operationalLayer);
operationalLayers.Add(operationalLayer);
}
_map.OperationalLayers.Clear();

Envelope extent = _mapViewSettings.VisibleExtent; // MapViewController.MapView.VisibleArea.Extent;

map.InitialViewpoint = new Viewpoint(extent);

map.OperationalLayers = operationalLayers;

map.Basemap.BaseLayers[0].Name = "Basemap";
_map = map;

_eventAggregator.GetEvent<MapLoadedEvent>().Publish(new MapLoadedEventArgs(_map));
}

View solution in original post

4 Replies
MortenNielsen
Esri Frequent Contributor

The exception means you're adding a layer to a map, when it's already in a map.

Reply
0 Kudos
PrashantKirpan
Occasional Contributor

Thanks Morten for reply,

First, I have added all layers to map and then send operational layers reference Map.OperationalLayers to other user control. Other control extracts layers from reference and add into his own collection - here i am getting exception 

I defined collection as below and bind OperationalLayers  property to user control.

public LayerCollection OperationalLayers { get; set; } = new LayerCollection();

I am quite sure that I am not adding layer in map.operational layer collection. Is there any reference issue with using LayerCollection  class?

Regards,

Prashant 

Reply
0 Kudos
JoeHershman
MVP Regular Contributor

Yes, but the Layer object is in a different OperationalLayers collection.  It is not that you have created a new LayerCollection.  You have to remove the layer from the first map in order to add it to the new map.

This is a sample to how the basemap was switched out and the layers had to be removed and add anew 

private void ResetMapLayers(Map map)
{
LayerCollection operationalLayers = new LayerCollection();
Layer[] tempLayers = new Layer[_map.OperationalLayers.Count];
_map.OperationalLayers.CopyTo(tempLayers, 0);

foreach (var operationalLayer in tempLayers)
{
_map.OperationalLayers.Remove(operationalLayer);
operationalLayers.Add(operationalLayer);
}
_map.OperationalLayers.Clear();

Envelope extent = _mapViewSettings.VisibleExtent; // MapViewController.MapView.VisibleArea.Extent;

map.InitialViewpoint = new Viewpoint(extent);

map.OperationalLayers = operationalLayers;

map.Basemap.BaseLayers[0].Name = "Basemap";
_map = map;

_eventAggregator.GetEvent<MapLoadedEvent>().Publish(new MapLoadedEventArgs(_map));
}

View solution in original post

PrashantKirpan
Occasional Contributor

Thanks Joe for sample code, really helps me to find out root cause of error.

I have just tried below code (instead of LayerCollection i used base layer class in observable collection) and that works for me without modifying map.OperationalLayers but I am not sure whether this is a correct approach or not.

Because operational layer reference is used in couple of user controls so probably it may create an issue if I continuously modify map.operationallayers object on runtime.

LayerListControlViewModel.cs

public ObservableCollection<Layer> OperationalLayers { get; set; } = new ObservableCollection<Layer>();

 public void InitializeLayerListControl(Map mapObj)
        {     
                foreach (var item in mapObj.OperationalLayers)
                {
                   //business logic
                   OperationalLayers.Add(item);
               }
         }

Regards,

Prashant

Reply
0 Kudos