I have a button on a proWindow that is attempting to flash a feature on the map. I use ShowDialog to show the proWindow which freezes the application so the user can interact with the window. When the button is clicked on the proWindow, the application just freezes and the feature is not flashed. I have attached the code that shows the implementation of the button that should flash the feature in the view model.
The code below is how I am instantiating the proWindow
Solved! Go to Solution.
Ok, that makes sense now. Yes, this will be a problem. Besides running your work on an asynchronous thread, QueuedTask.Run is also used to manage the ArcGIS Pro state, meaning that tasks like drawing, selection, geometry, and apparently cursor operations are 'serialized' and executed in a certain sequence. So if you execute a modal dialog from within such an operation you in effect 'block' the next QueuedTask.Run task, which in your case is the flashing of the geometry from within your dialog. You can bring up the ArcGIS Pro Diagnostic Monitor using the (Alt + Ctrl + M keys from within ArcGIS Pro) to view the health of ArcGIS Pro's threads.
In order to get this to work properly you have to change your workflow a bit. In your rowcursor you have to fill a collection of object ids, geometries (make sure to clone), etc. (collect whatever you need for your business logic) and once the collection is complete (you are done with queuedtask.run and back on the UI thread) you can then use that collection to process your records one by one. Flashing of geometries, updating of records, etc. should work unhindered. I have used this in the past especially for bulk updates or deletes.
I tried this using a Modal ProWindow and didn't experience the hang:
and the selected polygon is flashed as expected, using the code snippet below.
try
{
var oid = long.Parse(ObjectId.Text);
var layerName = FeatureLayerName.Text;
var lineLayer = MapView.Active.Map.GetLayersAsFlattenedList()
.OfType<FeatureLayer>()
.Where(lyr =>
lyr.Name == layerName).FirstOrDefault() as FeatureLayer;
await QueuedTask.Run(() =>
{
MapView.Active.FlashFeature(lineLayer, oid);
});
}
catch (Exception ex)
{
MessageBox.Show($@"Exception: {ex.Message}");
}
I will try MVVM next, but i can't imagine that this makes a difference. Try surrounding your code with a try ... catch ... just in case there's issues with code itself.
I tried the Mvvm version of ProWindow as well and was not able to duplicate the issue you reported. i am using 2.5 of the Pro SDK.
Wolfgang Kaiser, I don't know if you can tell from my code but I am opening the proWindow from inside a rowCursor (I open a proWindow for each row as I loop through). I utilise the Using statement which has to be inside a queuedTask.Run. To open the proWindow inside the queuedTask.Run, I am using Application.Current.Dispatcher.Invoke to push the proWindow out to the main thread. I believe this is the source of my problems. When I just open the proWindow with the click of a button, the flashing works fine but the issue comes when I open the proWindow from inside the cursor (utilising Application.Current.Dispatcher.Invoke). When the proWindow is opened this way, the flashing of the feature just hangs and never happens. I added a try catch but I don't receive any messages because the application just hangs once I click the button.
Ok, that makes sense now. Yes, this will be a problem. Besides running your work on an asynchronous thread, QueuedTask.Run is also used to manage the ArcGIS Pro state, meaning that tasks like drawing, selection, geometry, and apparently cursor operations are 'serialized' and executed in a certain sequence. So if you execute a modal dialog from within such an operation you in effect 'block' the next QueuedTask.Run task, which in your case is the flashing of the geometry from within your dialog. You can bring up the ArcGIS Pro Diagnostic Monitor using the (Alt + Ctrl + M keys from within ArcGIS Pro) to view the health of ArcGIS Pro's threads.
In order to get this to work properly you have to change your workflow a bit. In your rowcursor you have to fill a collection of object ids, geometries (make sure to clone), etc. (collect whatever you need for your business logic) and once the collection is complete (you are done with queuedtask.run and back on the UI thread) you can then use that collection to process your records one by one. Flashing of geometries, updating of records, etc. should work unhindered. I have used this in the past especially for bulk updates or deletes.
Using a collection worked perfectly. Thank you.