I would expect the following code to essentially clone the top layer in the map. It does create a new featurelayer that points to the Uri, but calling SetDefinition has no discernible effect.
private void Test()
{
var def = MapView.Active.Map.Layers[0].GetDefinition() as CIMFeatureLayer;
var conn = def.FeatureTable.DataConnection as CIMStandardDataConnection;
var folder = conn.WorkspaceConnectionString.Split('=')[1];
if (conn.WorkspaceFactory != WorkspaceFactory.Shapefile)
throw new Exception("test only works with shapefile layers");
var url = Path.Combine(folder, conn.Dataset + ".shp");
var fLayer = LayerFactory.CreateFeatureLayer(new Uri(url), MapView.Active.Map, 1);
fLayer.SetName("my layer");
// name remains "my layer" Setdefinition has no discernible effect
fLayer.SetDefinition(def);
}
Here's a simpler example. SetDefinition doesn't do anything from what I can tell.
private void Test()
{
var def = MapView.Active.Map.Layers[0].GetDefinition() as CIMFeatureLayer;
var fLayer = LayerFactory.CreateLayer(def.FeatureTable.DataConnection,MapView.Active.Map) as FeatureLayer;
fLayer.SetName("my layer");
// name remains "my layer" Setdefinition has no discernable effect
fLayer.SetDefinition(def);
}
Get and Set definition are a transactional pair. That is, you have to "get" a layer's definition, change it, then "set" it (or commit it) back to the repository. Think of it like a record in a database. It has an id and some other identifier information. It cannot be shared. In your code above I would imagine that the layer in
MapView.Active.Map.Layers[0]
will have had its name changed to "my layer". Ditto for the code sample above.
Actually, I looked closer at your code. In retrospect, it looks like you may be overwriting your change. For
MapView.Active.Map.Layers[0]
to have been changed you would have needed to have updated its definition before the
set (on flayer). Either way, the key is you have to get a definition, change it, then
set it back.
Thanks for replying Charles.
When I open a .lyrx file in a text editor, I see that it contains a CIMLayerDocument, which has a list of CIMLayers (e.g. CIMFeatureLayer etc.) When I choose to add data and select a .lyrx file behind the scenes Pro is turning definitions into layers. I want to be able to do something similar. Is this functionality exposed by the API?
If not, I think Esri really needs to add another overload to LayerFactory.CreateLayer which accepts a CIMLayer definition.
Otherwise, if there is a bug in SetDefinition, perhaps I could accomplish this once the bug is fixed.
Use LayerFactory.CreateLayer directly with the layer file....or....is that not doing what you want?
I think I resolved this by setting the URI of the definition to that of the newly created layer before applying.
Any known ill side-effects from doing this?
def.URI = fLayer.GetDefinition().URI;
fLayer.SetDefinintion(def);