|
POST
|
Your Module class implementation is a singleton and hence should be home of your license time out code (just add your code in the Module class constructor). By default, the Module class is executed just-in-time (JIT) when a user is using the add-in or the class is always instantiated when Pro starts up, if the 'autoLoad' attribute in the 'insertModule' tag is set to 'true' in the config.daml (see: ProConcepts Framework · Esri/arcgis-pro-sdk Wiki (github.com)) Also there's some information about ArcGIS Pro Add-in licensing - maybe not applicable for your use case: ProGuide License Your Add in · Esri/arcgis-pro-sdk Wiki (github.com)
... View more
08-24-2022
09:40 AM
|
0
|
1
|
1978
|
|
POST
|
Uma's suggestion works only for group layers, if you want a more general way to traverse the layer hierarchy you have to use the Layers collection of the Map class, as suggest by Uma. But when you iterate through the layers you need to look at the real type of the layer object (in essence each class that derives from the Layer class) and if the derived type has a Layers collection you then iterate into that sub layer collection. Below is a sample implementation, however, the implementation is incomplete because it only looks at AnnotationLayers and CompositeLayers as 2nd level entries in the TOC (there are more classes the derive from the Layer class and that have a Layers collection). protected override void OnClick()
{
try
{
var mva = MapView.Active;
if (mva == null) return;
var layers = mva.Map.Layers;
StringBuilder sb = new();
GetLayers(layers, sb, "");
MessageBox.Show(sb.ToString());
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
private static bool GetLayers(ReadOnlyObservableCollection<Layer> layers, StringBuilder sb, string indent)
{
foreach (var layer in layers)
{
var lyrName = layer.Name.Substring(0, Math.Min(40, layer.Name.Length));
sb.AppendLine($@"{indent}{lyrName} {layer.GetType().Name}");
if (layer is AnnotationLayer annoLyr)
{
GetLayers(annoLyr.Layers, sb, indent + " ");
continue;
}
if (layer is CompositeLayer compositeLyr)
{
GetLayers(compositeLyr.Layers, sb, indent + " ");
continue;
}
}
return true;
}
... View more
08-22-2022
06:35 PM
|
1
|
0
|
993
|
|
POST
|
ArcGIS Pro has its own error handling, not sure if or how that interferes with your Sentry implementation. If you want to use some type of diagnostic error handling, you can look here: ProConcepts Framework · Esri/arcgis-pro-sdk Wiki (github.com)
... View more
08-22-2022
01:30 PM
|
1
|
0
|
605
|
|
POST
|
As for libraries referenced in your Add-in make sure that you set the 'Copy Local' to yes for that library file: This should ensure that the dll is copied into the add-in's executable folder. Having not used GDAL, I would suggest following the debugging steps suggested by @DHuantes
... View more
08-22-2022
12:15 PM
|
1
|
0
|
2888
|
|
POST
|
You can define a reference to your view model in your Module. Since the Module class is a singleton you can then use that reference from your external class. Look at this example: arcgis-pro-sdk-community-samples/Map-Exploration/MapToolIdentifyWithDockpane at master · Esri/arcgis-pro-sdk-community-samples (github.com) in this sample the reference to the view modal is defined in the Module class as follows: internal static MapToolIdentifyDockpaneViewModel MapToolIdentifyDockpaneVM { get; set; } In the Ctor of the view model that 'global accessible' reference is initialized: protected MapToolIdentifyDockpaneViewModel()
{
// register self with Module class
Module1.MapToolIdentifyDockpaneVM = this;
} And it is then used in an external class (the tool in this case) here (https://github.com/Esri/arcgis-pro-sdk-community-samples/tree/master/Framework/DockpaneSimple 😞 protected override async Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
Module1.MapToolIdentifyDockpaneVM.ClearListOfFeatures();
await QueuedTask.Run(() =>
{
Module1.MapToolIdentifyDockpaneVM.AddToListOfFeatures($@"Layer: {featLyr.Name} obj id: {feat.GetObjectID()} Display Expression: {displayExp}");
});
return true;
} If you call your progressbar updates from a background thread, you might want to consider the following method that ensure execution on the UI thread (sample: arcgis-pro-sdk-community-samples/Map-Exploration/MapToolIdentifyWithDockpane at master · Esri/arcgis-pro-sdk-community-samples (github.com)😞 /// <summary>
/// utility function to enable an action to run on the UI thread (if not already)
/// </summary>
/// <param name="action">the action to execute</param>
/// <returns></returns>
internal static Task RunOnUIThread(Action action)
{
if (OnUIThread)
{
action();
return Task.FromResult(0);
}
else
return Task.Factory.StartNew(action, System.Threading.CancellationToken.None, TaskCreationOptions.None, QueuedTask.UIScheduler);
}
/// <summary>
/// determines if the application is currently on the UI thread
/// </summary>
private static bool OnUIThread
{
get
{
if (FrameworkApplication.TestMode)
return QueuedTask.OnWorker;
else
return System.Windows.Application.Current.Dispatcher.CheckAccess();
}
}
... View more
08-17-2022
08:23 AM
|
2
|
1
|
951
|
|
POST
|
Hi Tim, The upcoming release 3.1 is capable of adding 'Topology layers' to the TOC. I used this code snippet to test this: var path = @"C:\Data\Topology\GrandTeton.gdb\BackCountry";
Uri uri = new Uri(path);
await QueuedTask.Run(() =>
{
var item = ItemFactory.Instance.Create(uri.AbsolutePath);
if (!LayerFactory.Instance.CanCreateLayerFrom(item)) return;
var topoLyrParams = new TopologyLayerCreationParams(item);
LayerFactory.Instance.CreateLayer<TopologyLayer>(topoLyrParams, MapView.Active.Map);
}); Both TopologyLayer and TopologyLayerCreationParams were added in 3.1 to support this functionality.
... View more
08-17-2022
07:52 AM
|
0
|
1
|
2574
|
|
POST
|
Hi Pete, I think that the problem is that you are specifying the 'length' unit instead of the 'area' unit parameter. The following snippet worked for me (notice that i inserted "" as the length unit before the area parameter): var inputLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().First(l => l.Name.Equals(layerName));
var toolName = "management.CalculateGeometryAttributes";//based on my GP tool cache
var fieldParams = "TheInteger AREA";
var unit = "SQUARE_METERS";
var calcParams = Geoprocessing.MakeValueArray(
new object[] { inputLayer, fieldParams, "", unit, MapView.Active.Map.SpatialReference });
IGPResult result = await Geoprocessing.ExecuteToolAsync(toolName, calcParams, null, new CancelableProgressorSource(progDlg).Progressor, GPExecuteToolFlags.Default);
... View more
08-16-2022
02:54 PM
|
1
|
1
|
1879
|
|
POST
|
I think to duplicate this functionality will be a lot of work. So why can't you use the built-in tool: ICommand cmd = FrameworkApplication.GetPlugInWrapper("esri_editing_EditVerticesMove") as ICommand;
if ((cmd != null) && cmd.CanExecute(null))
cmd.Execute(null);
... View more
08-11-2022
02:26 PM
|
0
|
0
|
1129
|
|
POST
|
Regardless of knowing that a multi-layer removal included an 'allowed' layer, you can only remove the complete undo operation from OperationManager. It's not possible to just remove one part of the undo operation (i.e., the layer you don't want to have re-added again). Since it's an all or nothing [removal from the Undo stack] scenario, I would suggest removing an undo operation if the LayersRemovedEvent contained at least one of the layers that cannot be re-added to the map. If the LayersRemovedEvent only contained layers that can be re-added don't do anything with the undo stack.
... View more
08-11-2022
11:25 AM
|
0
|
0
|
2713
|
|
POST
|
You have to check if the operation name starts with the string "Remove" and ends with your layer name or the string "layers". If you have multi-language support, you have to use the proper translation of those strings (best implemented through the corresponding language resource file). This will support the single layer delete and deletion of multiple layers:
... View more
08-11-2022
09:38 AM
|
0
|
1
|
2717
|
|
POST
|
I found that this works in my test code and doesn't require a timer, however, you have to try this in your environment in order to verify that it works for you. Don't use a debugger and breakpoints when you debug this snippet it will change the thread execution sequence. Also as mentioned above your FindUndoOperations logic still requires some work. Charlie mentioned that various async operations still have to complete before OperationManager's queue reflects the true state so i decided to try executing the OperationManager related code on the UI thread once the UI thread is idle again, clearly a workaround, but it seemed to work for me. public static void RemoveUndoOperations(string opName)
{
if (MapView.Active?.Map == null) { return; }
QueuedTask.Run(async () =>
{
await System.Windows.Application.Current.Dispatcher.BeginInvoke(new Action(() =>
{
OperationManager opManager = MapView.Active.Map.OperationManager;
List<Operation> ops = opManager.FindUndoOperations(o => o.Name.Contains(opName));
foreach (Operation op in ops)
{
var opDetail = $@"Operation: {op.Name} canundo: {op.CanUndo} cat: {op.Category} sub: {op.SubCategory}";
System.Diagnostics.Trace.WriteLine(opDetail);
opManager.RemoveUndoOperation(op);
}
}), DispatcherPriority.ApplicationIdle);
});
}
... View more
08-11-2022
08:36 AM
|
1
|
1
|
2724
|
|
POST
|
I was able to duplicate the problem and you are correct in that the Undo operation doesn't appear to get added until after the LayersRemovedEvent fires. I am trying to find a workaround, but you will have to modify your .FindUndoOperations logic as well. If you remove more than one layer at the same time the Operation Name doesn't contain the layer name. Also, any other operation (like adding a layer) would be removed from the stack as well.
... View more
08-10-2022
12:50 PM
|
0
|
0
|
2748
|
|
POST
|
This is not something that we support with the ArcGIS Pro API. That being said, we don't see a reason for this not to work. Geometry objects in the Pro API are immutable, so there is no risk of conflict when accessing such objects from multiple threads. Other Pro API objects that are mutated or need to maintain state are not well suited for a multi-threaded application (i.e. GeoDatabase RowCursor).
... View more
08-09-2022
03:39 PM
|
0
|
0
|
630
|
|
POST
|
Hi Tom, The Migration tool (VSIX) only migrates your solution (or project file) from .Net Framework to .Net 6.0, it does not make changes to you any Nugets or dependent assemblies that are required by the move to .Net 6.0. System.Drawing.Common is one of those dependent assemblies that requires a change when moving to .Net 6.0. Under .Net Framework you used to be able to include a reference to System.Drawing.Common, but with .Net 6.0 you have to use the System.Drawing.Common Nuget (6.0.0) instead. There is a sample called MultipatchBuilderEx that was migrated from 2.9 and it does show the final project composition that you are looking for: I think you might have to remove the old 4.0 reference to System.Drawing.Common and add the NuGet reference and you can't have both.
... View more
08-09-2022
09:06 AM
|
1
|
1
|
3837
|
|
POST
|
When MapTool.UseSelection is true and your MapTool does sketching (i.e. i used SketchType = SketchGeometryType.Line in my sample), you can start sketching and the sketch (in progress) is saved as soon as you hold down the SHIFT key. Here i am digitizing my line sketch: Then i hold down my Shift Key and the Sketch state is preserved. Note that the sketching toolbar disappears as soon as you hold down the Shift key. Now with the Shift Key down i am in selection mode and i can now select different features (selection by Rectangle): When i finish any selection (by finishing the rubberband selection with the shift key still down) the OnSelectionChangedAsync method is called with the MapSelectionChangedEventArgs parameter showing the change in selection. Once i let the Shift key go, the Sketch state is restored and i can resume sketching where i left off before i held down the Shift key. The sketch tool bar also reappears.
... View more
08-08-2022
10:06 AM
|
0
|
0
|
760
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 10-07-2025 07:27 AM | |
| 2 | 4 weeks ago | |
| 1 | 07-30-2025 12:03 PM | |
| 1 | 10-06-2025 01:19 PM | |
| 1 | 10-06-2025 10:37 AM |
| Online Status |
Offline
|
| Date Last Visited |
2 weeks ago
|