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.
1. MapControlViewModel
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
Solved! Go to Solution.
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));
}
The exception means you're adding a layer to a map, when it's already in a map.
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
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));
}
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 logicOperationalLayers.Add(item);}}
Regards,
Prashant