|
POST
|
Hi M, Sorry for the late reply, but I checked back with some of my colleagues to make sure that my findings were correct. So to answer your question: "So this is a drastic change then?" According to the documentation "starting a new EditOperation within a Row Event" is not supported in 2.2 and this was also true in 2.1, so this is not a change in 2.2. As to why this worked for you in 2.1 I can only speculate, but when I tried this workflow in my sample add-ins in 2.1 I was not able to get it to work reliably. That being said let me answer your last question: "You are saying I can't call row change from within a row change?" If you look at the sample ModifyNewlyAddedFeatures that I published it includes the "enable Store()" option which calls .Store() on the Row Event's subject row. Calling Store() from within a Row Event can cause a Row Event to be triggered recursively and you can use the args.Guid parameter to determine re-entrance as illustrated by the sample. Finally to address your 2nd paragraph "My polygon features rely and other polygon features of a different class." I will modify my sample code so that creating or modifying a feature leads to changes in other features in order to emulate your requirements and post the updated sample.
... View more
08-07-2018
10:58 AM
|
0
|
1
|
1675
|
|
POST
|
I usually don't use that workflow path. I reported the issue to the Geonet team.
... View more
08-02-2018
11:43 AM
|
0
|
0
|
2293
|
|
POST
|
I usually use the links I get through my notification emails: I get two 'inbox' links, and yes you are correct only one works as it provides the '...' menu option.
... View more
08-02-2018
11:31 AM
|
0
|
0
|
2293
|
|
POST
|
Actually the 'SyntaxHighlighter' feature is available, but not as a default menu selection. You first click the "..." menu option on your reply, then you click the 'More' pull-down and select the 'SyntaxHightlighter' from the drop-down menu and you can add you code snippet. It took me a while to remember this 😉 namespace ProAppModule1
{
internal class Button1 : Button
{
protected override void OnClick()
{
MessageBox.Show(@"Hello world!");
}
}
}
... View more
08-02-2018
10:39 AM
|
0
|
3
|
2293
|
|
POST
|
Hi Daniel, One common pattern is to use the Module1 class to hold your selected values and allow other controls to access the value through the Module1 class (which is a singleton). So in your example you need to add a public property, which I call 'MyComboboxValue', to the Module1 class in order to hold the combobox selection: internal class Module1 : Module
{
private static Module1 _this = null;
/// <summary>
/// Retrieve the singleton instance to this module here
/// </summary>
public static Module1 Current
{
...
}
// Add your 'shared' properties here:
public string MyComboboxValue { get; set; }
...
} Now you need to store the ComboBox selection by modifying the ComboBox1 class' OnSelectionChange method: /// <summary>
/// The on comboBox selection change event.
/// </summary>
/// <param name="item">The newly selected combo box item</param>
protected override void OnSelectionChange(ComboBoxItem item)
{
if (item == null) return;
// save the selection in your module1 class
Module1.Current.MyComboboxValue = item.Text;
} Finally you can use the 'shared' property throughout your add-in by using the Modul1 class' Current member: Module1.Current.MyComboboxValue. For example: MessageBox.Show($@"From Combo Box: {Module1.Current.MyComboboxValue}"); If you need to access any values from another add-in you can use a Pro FrameworkApplication function to get the Module1 instance like this: ((Module1)FrameworkApplication.FindModule("ProAppModule1_Module")).MyComboboxValue Hope this helps
... View more
08-02-2018
10:20 AM
|
1
|
0
|
1561
|
|
POST
|
I created a new add-in using the ArcObjects SDK 10.6. I used the VB 'ArcMap Add-in' Project Template wizard to create a new add-in by selecting a button on the pop-up wizard. When I built the application everything worked as expected. You should check if your references are resolved properly - here is my screen with the config.designer.vb file and the references in the solution explorer. Again as Sean mentioned, this is the wrong forum for your ArcObjects question.
... View more
08-01-2018
11:22 AM
|
0
|
0
|
1199
|
|
POST
|
I tried the following code snippet by using the data from community samples and tried the code below with both ArcGIS Pro 2.2 and 2.2.1. It worked with both versions. Can you please elaborate a bit about the content of the layer file? try
{
QueuedTask.Run(() =>
{
Uri myUri = new Uri(@"C:\Data\SDK\Default2DPointSymbols.lyrx");
Layer newlayer = LayerFactory.Instance.CreateFeatureLayer(myUri,
MapView.Active.Map, LayerPosition.AddToTop);
});
}
catch (Exception ex)
{
MessageBox.Show($@"Error: {ex.ToString()}");
}
... View more
08-01-2018
10:57 AM
|
1
|
0
|
1460
|
|
POST
|
There is a community sample that delves into states and conditions that might be of help here: Framework - ConditionQuery
... View more
08-01-2018
10:45 AM
|
0
|
0
|
2723
|
|
POST
|
Hi Steve, I had to remove all my add-ins and tabs first before I was able to duplicate your problem. It appears to be a bug. I will try to make a simple small add-in to duplicate the issue and report the bug. Thanks, Wolf
... View more
07-31-2018
02:48 PM
|
0
|
0
|
1958
|
|
POST
|
Hi Scott, You can try to subscribe to this event: "ArcGIS.Desktop.Layouts.Events.LayoutViewEvent" and in the event handler you can look at the Type and IsReady attributes as shown in the code snippet below. If args.Type is "Initialized" and args.LayoutView.IsReady is true your layout is ready to be 'processed'. However, as I tested this event I did notice that the events are not kicked off if an 'active' layout is open in your Project file, instead the events only work if you change the active layout after the project is loaded. I relayed your requirements and the issues I found to the development team and they are looking to fix these issues for the 2.3 release. Below is the code I added to my Module class, ActiveLayoutEventsPaneViewModel is a property that defines my status display Dockpane. I also set the 'autoload' attribute for the insertModule tag in the config.daml to true. private static void OnLayoutViewEvent (ArcGIS.Desktop.Layouts.Events.LayoutViewEventArgs args)
{
// For display in my dockpane:
if (ActiveLayoutEventsPaneViewModel != null)
{
var status = $@"LayoutViewEvent: {args.LayoutView.Layout.Name}{Environment.NewLine} arg Type: {args.Type.ToString()}";
if (args.LayoutView.IsReady) status += $@"{Environment.NewLine} layoutView is Ready";
ActiveLayoutEventsPaneViewModel.UpdateStatusText(status);
}
}
/// <summary>
/// gives this add-ins a chance to initialize itself and return its status to the calling Framework.
/// </summary>
/// <returns></returns>
protected override bool Initialize()
{
// initialize layout events
_subscriptionToken = ArcGIS.Desktop.Layouts.Events.LayoutViewEvent.Subscribe(OnLayoutViewEvent);
return base.Initialize();
}
And this is the result after I opened a layout view: I hope this helps, - Wolf
... View more
07-31-2018
11:37 AM
|
0
|
0
|
1163
|
|
POST
|
Hi Steve, I built and tried your app and was not able to duplicate the described behavior, I had to open the custom control by clicking the drop-down button - so maybe you already modified the behavior. I was using Pro 2.2 and your add-in code from yesterday afternoon. It appears that the custom control doesn't become visible until the drop-down is used. The only time the custom control was moved from its 'design' position was when I placed the ribbon tab close to the margin of my screen. I have a multi-display system, so this includes the transition area between two screens.
... View more
07-31-2018
09:56 AM
|
0
|
0
|
1958
|
|
POST
|
Hi Steve, Sorry - I posted this to one of your other threads accidentally: I looked at Narelle's example and at your code (which has changed in the meantime) and I did notice a small difference: When you call QueuedTask.Run you need to specify the ProgressorSource parameter. In the snippet I had copied earlier I noticed the missed the parameter: , status.Progressor as you can see here: private async Task CreateFacilityAsync(ProgressorSource status) => await QueuedTask.Run(() => { … }, status.Progressor); Also be aware that ProgressorSource status message updates are 'relayed' back to the GUI via a message queue and only processed if the GUI thread gets around to it. Consequently some messages might be lost because once the GUI processes an update, any subsequent update can 'override' it, if multiple 'backed up' updates are waiting in the message queue. I think Narelle added the 'Task.Delay' statements to allow the GUI sufficient time to catch up. In the past I have also used a ProgressBar and Status text fields in my DockPanes to give users a feedback on progress (in some cases that fit my workflow requirements better that a popup dialog). In this case you need to make sure that any updates to your ViewModule properties are thread save. Here is a snippet that worked for me (this snippet updates a text property from any thread): /// <summary> /// UpdateStatusText can be called from any thread to update the TxtStatus /// text property in my ViewModel, also adds a newline at the end of the text. /// </summary> /// <param name="text"></param> public void UpdateStatusText(string text) { if (System.Windows.Application.Current.Dispatcher.CheckAccess()) { TxtStatus += text + Environment.NewLine; } else { ProApp.Current.Dispatcher.BeginInvoke(DispatcherPriority.Normal, (Action)(() => { TxtStatus += text + Environment.NewLine; })); } } Hope this helps, Wolf
... View more
07-31-2018
09:42 AM
|
0
|
0
|
5233
|
|
POST
|
I took my sample code that I used to duplicate your workflow and published the sample on 'community samples' GitHub repo here: Modify Newly Added Features. Hopefully this sample helps when you refactor the code for 2.2. There are a few issues that I would like to highlight in the ProConcepts Editing document, specifically in the Row Events section at the end of the document: 1. "The row events are published during the execution of the edit operation (whereas the EditCompletedEvent is published after the entire edit operation has completed)." This means that the row event intercepts your row creation/update before the transaction is completed, you can still cancel any changes from within any row event. You cannot commit any data changes while you are processing any row events which I think is what you do in your code here: //Make the initial commit to get the field to be visible with the definition query
await pmi.CommitChangesAsync(); If your intend is to display a newly created feature that satisfied the current 'definition query' on that layer, you should use an appropriate 'editing / creation template' that contains valid values so that the 'definition query' results are true (hence your new feature is shown on the map view) from the get-go. You can make changes to the args.row fields directly if need be (see the sample) and you can call .Store() on the row to save these changes, but this will result in a recursive row event (again see the sample for details). 2. "If you need to edit additional tables within the RowEvent you must use the ArcGIS.Core.Data API to edit the tables directly. Do not use a new edit operation to create or modify features or rows in your RowEvent callbacks." I think I saw your code snippets using an another EditOperation in one of the functions that are instantiated from the row events. In 2.2 this will not work. Instead, as indicated by the documentation, you must use the ArcGiS.Core.Data API to change other data sources directly (in the sample I show this when I update the tracking/logging table). Hopefully this will help you out. Wolf
... View more
07-27-2018
02:15 PM
|
0
|
3
|
2267
|
|
POST
|
Sorry about the delayed reply. I looked over your snippets of code and tried to implement a sample to perform the same workflow. In my workflow I use RowChangedEvent and RowCreatedEvent subscriptions to make changes to the geometry of the subject row. The workflow looks like this: I modify an existing polygon or create a new one. Once the RowChanged / Created Event a firing, I use the new geometry and union all existing intersects of the new polygon with other polygons in that same layer. I then 'subtract' that union of intersects (if any) with my new geometry and overwrite the sketched geometry. So here is what it looks like in my add-in: First I 'create' a new polygon to my existing layer: After I complete the sketch my Row Created event kicks in and the add-in logic to change my geometry run to prevent that my newly created geometry doesn't overlay any other polygons. I also update a description field in my new or modified feature to show if the sketched geometry was changed or not. Hopefully I captured what you do in your add-in. Just in case I did here are some snippets from the sample: // this is the feature layer that the add-in will process ... needs to be set somewhere in your add-in
private FeatureLayer _workedOnFeatureLayer = null;
// setup event listening ... somewhere in your code
QueuedTask.Run(() => {
_onRowChangedEvent = RowChangedEvent.Subscribe(OnRowChangedEvent, _workedOnFeatureLayer.GetTable());
_onRowCreatedEvent = RowCreatedEvent.Subscribe(OnRowCreatedEvent, _workedOnFeatureLayer.GetTable());
});
// ....
/// <summary>
/// Called for each row change
/// </summary>
/// <param name="args"></param>
private void OnRowChangedEvent(RowChangedEventArgs args)
{
UpdateStatusText ($@"Row changed: {args.EditType}");
UpdateRowIfNeeded(args);
}
/// <summary>
/// called for each newly created row
/// </summary>
/// <param name="args">
/// </param>
private void OnRowCreatedEvent(RowChangedEventArgs args)
{
UpdateStatusText ($@"Row created: {args.EditType}");
UpdateRowIfNeeded(args);
}
private void UpdateRowIfNeeded (RowChangedEventArgs args)
{
try {
var row = args.Row;
var geom = row["Shape"] as Geometry;
var rowCursorOverlayPoly = _workedOnFeatureLayer.Search (geom, SpatialRelationship.Overlaps);
Geometry geomOverlap = null;
while (rowCursorOverlayPoly.MoveNext())
{
var feature = rowCursorOverlayPoly.Current as Feature;
var geomOverlayPoly = feature.GetShape();
if (geomOverlayPoly == null) continue;
var geomDifference = GeometryEngine.Instance.Intersection(geom, geomOverlayPoly);
if (geomDifference == null) continue;
if (geomOverlap == null) {
geomOverlap = geomDifference;
continue;
}
geomOverlap = GeometryEngine.Instance.Union(geomOverlap, geomDifference);
}
if (!geomOverlap.IsNullOrEmpty())
{
args.Row["Description"] = "Corrected input polygon";
row["Shape"] = GeometryEngine.Instance.Difference(geom, geomOverlap);
}
else args.Row["Description"] = "No overlapping polygons found";
}
catch (Exception e) {
MessageBox.Show($@"Error in UpdateRowIfNeeded for OID: {args.Row.GetObjectID()} in {_workedOnFeatureLayer.Name}: {e.ToString()}");
}
}
Looks like my add-in works for both file and database connections, I will try a feature service tomorrow.
... View more
07-25-2018
05:04 PM
|
0
|
0
|
2266
|
|
POST
|
I tried the snippet and it appears to work fine. Do you call the 'Difference' method from within the context of an edit event or simply as a result of inspector.Load ? Also is the data source of the feature in _dataInspector a feature service? I want to setup the context in my sample to better match your workflow. Wolf
... View more
07-19-2018
05:09 PM
|
0
|
2
|
2266
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 10-29-2025 10:48 AM | |
| 1 | 05-24-2021 09:04 AM | |
| 1 | 12-03-2020 08:44 AM | |
| 1 | 10-07-2025 07:27 AM | |
| 2 | 12-29-2025 10:03 AM |
| Online Status |
Offline
|
| Date Last Visited |
03-30-2026
03:25 PM
|