If i can get the current index of layer A, I think I add one to the int to move layer B directly beneath it.
I need to get layer A's index in the Contents pane.
Help is appreciated.
Solved! Go to Solution.
Hi Mike
Here is some code snippet that recursively checks through all the layers (including group layers) to move the layer.
In this example the layer I want to move is the "US Cities layer". I want to move this layer to be below US Counties layer.
Thanks
Uma
protected override void OnClick()
{
var layerToMove = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(f => f.Name == "U.S. Cities").FirstOrDefault();
if (layerToMove == null)
{
MessageBox.Show("Layer U.S. Cities not found ");
return;
}
var moveBelowThisLayerName = "U.S. Counties (Generalized)";
//In order to move layerToMove, I need to know if the destination is a group layer and the zero based position it needs to move to.
Tuple<GroupLayer, int> moveToLayerPosition = FindLayerPosition(null, moveBelowThisLayerName);
if (moveToLayerPosition.Item2 == -1) {
MessageBox.Show($"Layer {moveBelowThisLayerName} not found ");
return;
}
QueuedTask.Run( () => {
if (moveToLayerPosition.Item1 != null) //layer gets moved into the group
moveToLayerPosition.Item1.MoveLayer(layerToMove, moveToLayerPosition.Item2);
else //Layer gets moved into the root
MapView.Active.Map.MoveLayer(layerToMove, moveToLayerPosition.Item2);
});
}
private Tuple<GroupLayer, int> FindLayerPosition(GroupLayer groupLayer, string moveToLayerNameBelow)
{
int index = 0;
foreach (var lyr in groupLayer != null? groupLayer.Layers : MapView.Active.Map.Layers)
{
index++;
if (lyr is GroupLayer)
{
//We descend into a group layer and search all the layers within.
var result = FindLayerPosition(lyr as GroupLayer, moveToLayerNameBelow);
if (result.Item2 >= 0)
return result;
continue;
}
if (moveToLayerNameBelow == lyr.Name) //We have a match
{
return new Tuple<GroupLayer, int>(groupLayer, index);
}
}
return new Tuple<GroupLayer, int>(null, -1);
}
Hi Mike
One way to do this is -
Thanks
Uma
Well,
GVar.index = 0;
FeatureLayer layer_A = map.FindLayers(lyrname).OfType<FeatureLayer>().FirstOrDefault() as FeatureLayer;
GroupLayer grp = map.FindLayers(grplyrname).OfType<GroupLayer>().FirstOrDefault() as GroupLayer;
int g = grp.Layers.IndexOf(layer_A); //when IN GroupLayer grp
int m = map.Layers.IndexOf(layer_A); //when merely in the active map
if (g == -1) //g will return -1 as the index if it isn't inside the GroupLayer grp
{
GVar.index = m; //sets the index value of layer_A from the map
}
else
{
GVar.index = g; //otherwise sets the index value of layer_A from the GroupLayer grp
}
int cci = GVar.index + 1; //will be the index placment of Layer_B
FeatureLayer layer_B = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(l => l.Name == "layer_B_name");
if (g == -1)
{
map.MoveLayer(layer_B, cci);
}
else
{
grp.MoveLayer(layer_B, cci);
}
This is good enough for now. However, If the user moves layer_A inside a group layer different from that specified, its index will default to -1 and place layer_B relative to its placement in the active map and not to the unspecified group layer. Further investigating Layer.Parent to identify the unspecified group layer in this scenario.
Thanks, Uma.
Hi Mike
Here is some code snippet that recursively checks through all the layers (including group layers) to move the layer.
In this example the layer I want to move is the "US Cities layer". I want to move this layer to be below US Counties layer.
Thanks
Uma
protected override void OnClick()
{
var layerToMove = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(f => f.Name == "U.S. Cities").FirstOrDefault();
if (layerToMove == null)
{
MessageBox.Show("Layer U.S. Cities not found ");
return;
}
var moveBelowThisLayerName = "U.S. Counties (Generalized)";
//In order to move layerToMove, I need to know if the destination is a group layer and the zero based position it needs to move to.
Tuple<GroupLayer, int> moveToLayerPosition = FindLayerPosition(null, moveBelowThisLayerName);
if (moveToLayerPosition.Item2 == -1) {
MessageBox.Show($"Layer {moveBelowThisLayerName} not found ");
return;
}
QueuedTask.Run( () => {
if (moveToLayerPosition.Item1 != null) //layer gets moved into the group
moveToLayerPosition.Item1.MoveLayer(layerToMove, moveToLayerPosition.Item2);
else //Layer gets moved into the root
MapView.Active.Map.MoveLayer(layerToMove, moveToLayerPosition.Item2);
});
}
private Tuple<GroupLayer, int> FindLayerPosition(GroupLayer groupLayer, string moveToLayerNameBelow)
{
int index = 0;
foreach (var lyr in groupLayer != null? groupLayer.Layers : MapView.Active.Map.Layers)
{
index++;
if (lyr is GroupLayer)
{
//We descend into a group layer and search all the layers within.
var result = FindLayerPosition(lyr as GroupLayer, moveToLayerNameBelow);
if (result.Item2 >= 0)
return result;
continue;
}
if (moveToLayerNameBelow == lyr.Name) //We have a match
{
return new Tuple<GroupLayer, int>(groupLayer, index);
}
}
return new Tuple<GroupLayer, int>(null, -1);
}
Uma,
I'm feeling pretty good about this approach. I was able to implement your footprint into my add-in tool.
I really appreciate your help.
private Tuple<GroupLayer, int> GetLyr_Loc(GroupLayer grplyr, string movebelowlayername)
{
Map map = MapView.Active.Map; //solution footprint provided by Uma Harano, esristaff 2019
int index = 0;
foreach (var lyr in grplyr != null ? grplyr.Layers : map.Layers)
{
index++;
if (lyr is GroupLayer)
{
//We descend into a group layer and search all the layers within.
Tuple<GroupLayer, int> result = GetLyr_Loc(lyr as GroupLayer, movebelowlayername);
if (result.Item2 >= 0)
return result;
continue;
}
if (movebelowlayername == lyr.Name) //We have a match
{
return new Tuple<GroupLayer, int>(grplyr, index);
}
}
return new Tuple<GroupLayer, int>(null, -1);
}
private async void cctvlstbx_MouseDoubleClick(object sender, MouseEventArgs e)
{
await ActMap();
Map map = MapView.Active.Map;
MapView MV = MapView.Active;
string lyrname = "Sewer File Geodatabase";
string sublyrname = "Sewer Mains"; //Check for Sewer Mains in TOC
string url = GVar.DL + @"gisdata\layers\" + lyrname + ".lyr";
Uri uri = new Uri(url);
string cctvguide = "ccTV Guide";
string url2 = GVar.DL + @"gisdata\layers\" + cctvguide + ".lyr";
Uri uri2 = new Uri(url2);
FeatureLayer lyrcheck3 = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(l => l.Name == sublyrname);
if (lyrcheck3 == null)
{
await QueuedTask.Run(() => LayerFactory.Instance.CreateFeatureLayer(uri, map));
}
FeatureLayer ssmain_lyr = map.FindLayers(sublyrname).OfType<FeatureLayer>().FirstOrDefault() as FeatureLayer;
if (ssmain_lyr.IsVisible == false)
{
await QueuedTask.Run(() =>
{
ssmain_lyr.SetVisibility(true);
});
}
FeatureLayer lyrchck = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(l => l.Name == cctvguide);
if (lyrchck == null)
{
if (GVar.cctvlyr == true)
{
string message = "Would you like to add the ccTV Guide layer for reference?";
string caption = " Add ccTV Guide?";
MessageBoxButtons buttons = MessageBoxButtons.YesNo;
MessageBoxIcon icon = MessageBoxIcon.Exclamation;
MessageBoxDefaultButton defbutton = MessageBoxDefaultButton.Button1;
MessageBoxOptions bxOpt = MessageBoxOptions.DefaultDesktopOnly;
DialogResult result;
result = MessageBox.Show(message, caption, buttons, icon, defbutton, bxOpt);
if (result == DialogResult.Yes)
{
await QueuedTask.Run(() => LayerFactory.Instance.CreateFeatureLayer(uri2, map));
await MV.RedrawAsync(true);
}
if (result == DialogResult.No)
{
GVar.cctvlyr = false;
}
};
}
FeatureLayer cctvlyr = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault(l => l.Name == cctvguide);
if (cctvlyr != null) //solution footprint provided by Uma Harano, esristaff 2019
{
//In order to move cctvlyr, I need to know if the destination is a group layer and the zero based position it needs to move to.
Tuple<GroupLayer, int> MoveTo_Loc = GetLyr_Loc(null, sublyrname);
await QueuedTask.Run(() =>
{
if (MoveTo_Loc.Item1 == null) //layer gets moved into the root
{
map.MoveLayer(cctvlyr, MoveTo_Loc.Item2);
}
else //Layer gets moved into the group
{
GVar.containername = MoveTo_Loc.Item1.Name;
MoveTo_Loc.Item1.MoveLayer(cctvlyr, MoveTo_Loc.Item2);
}
if (cctvlyr.IsVisible == false)
{
cctvlyr.SetVisibility(true);
}
});
}
GroupLayer sm_grp = map.FindLayers(GVar.containername).OfType<GroupLayer>().FirstOrDefault();
if (sm_grp != null && sm_grp.IsVisible == false)
{
await QueuedTask.Run(() =>
{
sm_grp.SetVisibility(true);
});
}
//further functions below...