POST
|
For what it's worth, here's how I solved the problem. Is seems it was the repeated call to ArcMap.Document.FocusMap.FeatureSelection that was breaking my add-in. If I instead store the focus map in a member variable IMap map and retrieve the feature selection by calling map.FeatureSelection is works just fine. using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.IO;
using System.Collections;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Desktop.AddIns;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System.Runtime.InteropServices;
namespace DfT.Maritime.DeepPort {
public class DeepPortExtension: ESRI.ArcGIS.Desktop.AddIns.Extension {
IMap map;
private static IActiveViewEvents_Event ViewEvents {
get { return ArcMap.Document.ActiveView as IActiveViewEvents_Event; }
}
public DeepPortExtension() {
}
protected override void OnStartup() {
}
protected override bool OnSetState(ExtensionState state) {
Init();
return base.OnSetState(state);
}
private void Init() {
if (ArcMap.Document.ActiveView.IsActive()) {
InitAddin();
} else {
ArcMap.Events.OpenDocument += delegate() {
InitAddin();
};
ArcMap.Events.NewDocument += delegate() {
InitAddin();
};
}
}
private void InitAddin() {
// Bind selection changed handler
ViewEvents.SelectionChanged += SelectionChanged_Handler;
//
// Store focus map in a member variable!!!
//
map = ArcMap.Document.FocusMap;
}
private void SelectionChanged_Handler() {
//
// Retrieve selected features from member variable!!!
//
ISelection selection = map.FeatureSelection;
IEnumFeature featuresEnum = (IEnumFeature)selection;
IEnumFeatureSetup featureSetup = (IEnumFeatureSetup)selection;
featureSetup.AllFields = true;
string message = "";
IFeature feature;
while ((feature = featuresEnum.Next()) != null) {
int fldID = feature.Fields.FindField("locode");
message += feature.get_Value(fldID).ToString() + ",";
}
System.Windows.Forms.MessageBox.Show(message);
Marshal.ReleaseComObject(featuresEnum);
Marshal.ReleaseComObject(featureSetup);
Marshal.ReleaseComObject(selection);
}
}
}
... View more
06-13-2015
05:05 AM
|
0
|
0
|
553
|
POST
|
All right, this bug is very odd. I have tried to force garbage collection but the only effect was that the SelectionChanged_Handler would get called only once upon selecting features. After that, the add-in would stop working as it does without the forced collection. I am no expert in using forced garbage collection, but this approach doesn't seem to be the answer to my problem and appears to be frowned upon by many C# programmes (that doesn't mean it's wrong, I know). I have altered the code to localize the problem. It seems that the issue is caused by the growing message string, i.e. the step message += feature.HasOID.ToString() + "\n"; (line 15.) The following code breaks as described previously: private void SelectionChanged_Handler() {
string message = "";
try {
ISelection selection = ArcMap.Document.FocusMap.FeatureSelection;
IEnumFeature featuresEnum = (IEnumFeature)selection;
IEnumFeatureSetup featureSetup = (IEnumFeatureSetup)selection;
featureSetup.AllFields = true;
IFeature feature;
while ((feature = featuresEnum.Next()) != null) {
message += feature.HasOID + ",";
Marshal.FinalReleaseComObject(feature);
}
Marshal.FinalReleaseComObject(featuresEnum);
Marshal.FinalReleaseComObject(featureSetup);
} catch (Exception e) {
System.Windows.Forms.MessageBox.Show(e.Message);
}
System.Windows.Forms.MessageBox.Show(message);
} No exception is caught, no error displayed, the add-in simply stops showing the message as expected and cannot be re-initialized in the Customize menu. However, the altered code below seems to run OK: private void SelectionChanged_Handler() {
List<string> message = new List<string>();
try {
ISelection selection = ArcMap.Document.FocusMap.FeatureSelection;
IEnumFeature featuresEnum = (IEnumFeature)selection;
IEnumFeatureSetup featureSetup = (IEnumFeatureSetup)selection;
featureSetup.AllFields = true;
IFeature feature;
while ((feature = featuresEnum.Next()) != null) {
message.Add(feature.HasOID.ToString());
Marshal.FinalReleaseComObject(feature);
}
Marshal.FinalReleaseComObject(featuresEnum);
Marshal.FinalReleaseComObject(featureSetup);
} catch (Exception e) {
System.Windows.Forms.MessageBox.Show(e.Message);
}
System.Windows.Forms.MessageBox.Show(String.Join(",", message.ToArray()));
message.Clear();
} Can someone explain what's going on behind the scene in these two cases?
... View more
06-10-2015
03:39 AM
|
0
|
0
|
553
|
POST
|
Yes. I have tried to wrap the whole block of code in a try..catch to no avail. Catching Exception doesn't seem to help, unfortunately, as none seems to be thrown...
... View more
06-09-2015
12:43 PM
|
0
|
1
|
553
|
POST
|
I am developing a simple add-in that will trigger an action after user selects features on the map. The action will essentially make sure a dockable window is open and in that window display information about the selected features. I have implemented a simple function that loops over selected features using IEnumFeature and collects their OIDs. To make sure the OIDs are present for all features in the selection, I set the IEnumFeatureSetup.AllFields = true. Now to the problem. After I've selected a number features several times (regardless of what features or how many I select), the SelectionChanged event stops from being fired. It appears as if the add-in has crashed, but no error message is displayed. This happens both in debug and production. If I try to restart the add-in by de-selecting it in the Customise->Extensions menu, I can no longer select it back. However, ArcMap works fine otherwise. To make the add-in work again I must restart ArcMap. I have done some naive memory usage inspection using Task Manager. Memory usage raises as I keep re-selecting features. Is this a memory leak? I am releasing the IEnum reference so this should, at least in theory, not be a problem. The features are pulled from a file geodatabase. They have 5 short text fields each and there is around 1300 of them. The more features I select at once, the sooner the add-in stops working (e.g. if I select all of the features in the map at once, the SelectionChanged event won't be fired again). I am developing in Arcobjects 10.1 SDK with Visual Studio 10 for C# Express using .NET 3.5. I cannot upgrade nor can I use .NET 4.0 due to client constraints. The add-in is being tested in ArcMap 10.1. using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Text;
using System.IO;
using System.Collections;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
using ESRI.ArcGIS.Desktop.AddIns;
using ESRI.ArcGIS.Geodatabase;
using ESRI.ArcGIS.Geometry;
using System.Runtime.InteropServices;
namespace DfT.Maritime.DeepPort {
public class DeepPortExtension: ESRI.ArcGIS.Desktop.AddIns.Extension {
private static IActiveViewEvents_Event ViewEvents {
get { return ArcMap.Document.ActiveView as IActiveViewEvents_Event; }
}
public DeepPortExtension() {
}
protected override void OnStartup() {
}
protected override bool OnSetState(ExtensionState state) {
Init();
return base.OnSetState(state);
}
private void Init() {
if (ArcMap.Document.ActiveView.IsActive()) {
InitAddin();
} else {
ArcMap.Events.OpenDocument += delegate() {
InitAddin();
};
ArcMap.Events.NewDocument += delegate() {
InitAddin();
};
}
}
private void InitAddin() {
// Bind selection changed handler
ViewEvents.SelectionChanged += SelectionChanged_Handler;
}
private void SelectionChanged_Handler() {
ISelection selection = ArcMap.Document.FocusMap.FeatureSelection;
IEnumFeature featuresEnum = (IEnumFeature)selection;
IEnumFeatureSetup featureSetup = (IEnumFeatureSetup)selection;
featureSetup.AllFields = true;
string message = "";
IFeature feature;
while ((feature = featuresEnum.Next()) != null) {
int fldID = feature.Fields.FindField("locode");
message += feature.get_Value(fldID).ToString() + ",";
}
System.Windows.Forms.MessageBox.Show(message);
Marshal.ReleaseComObject(featuresEnum);
Marshal.ReleaseComObject(featureSetup);
Marshal.ReleaseComObject(selection);
}
}
} Please help, this has been bugging me for the good part of the last week!
... View more
06-09-2015
11:59 AM
|
0
|
5
|
3741
|
POST
|
OK, here's a solution. Looping over the IEnumFeature doesn't ensure that all fields are returned, apparently. In my case this resulted in NO field values being returned, including the OID which was missing. I have managed to get the fields by setting the AllFields of the IEnumFeatureSetup to true. Code below illustrates the solution, hope this helps someone. IMxDocument doc = ArcMap.Application.Document as IMxDocument;
IMap map = doc.FocusMap;
// Retrieve selected features enum
IEnumFeature ftEnum = map.FeatureSelection as IEnumFeature;
IEnumFeatureSetup ftSetup = (IEnumFeatureSetup)ftEnum;
// Make sure ALL fields are returned
ftSetup.AllFields = true;
ftEnum.Reset();
IFeature ft;
while ((ft = ftEnum.Next()) != null) {
int fldID = ft.Fields.FindField("LOCODE");
message += ft.get_Value(fldID) + "\n";
}
... View more
06-02-2015
09:09 AM
|
0
|
1
|
571
|
POST
|
I'm trying to get a value of a particular field from selected features. The features are from a layer that contains data from a file geodatabase. The data has been imported from an excel spreasheet, the file geodatabase is set as the default geodatabase and the feature class appears to be registered with it (the "Register with Geodatabase" option in the Manage menu is disabled). I obtain IEnumFeature from the focused map's FeatureSelection: IMap map = ArcMap.Document.ActiveView.FocusMap;
IEnumFeature ftEnum = map.FeatureSelection as IEnumFeature; I then have a while loop that fetches selected features from the enum and tries to get a particular field value: IFeature ft = null;
while ((ft = ftEnum.Next()) != null) {
int fid = ft.Fields.FindField("LOCODE");
string locode = ft.get_Value(fid) as string;
} Now, the fid gets correctly assigned to 1, which is the index of the "LOCODE" field, but the returned value is null. I noticed that the features do not have OID associated with them. Why is that? If I export the feature class as a shapefile and add it to the map, the OIDs are set. But the "LOCODE" values are missing in either case. Why is this happening?
... View more
06-02-2015
08:08 AM
|
0
|
2
|
4129
|
POST
|
Yes it is. And getting to this point has helped me solve this! I finally figured I have to listen to ArcMap.Events.OpenDocument and bind the SelectionChanged only after the former has been fired. Thanks for you help, my final answer shows the working code.
... View more
06-01-2015
02:54 PM
|
0
|
1
|
1213
|
POST
|
After much trial and error, I have figured out how to solve this. My extension is configured to load automatically upon ArcMap startup and I must bind my action to the SelectionChanged on Document.ActiveView only after the ArcMap.Events.OpenDocument or ArcMap.Events.NewDocument have been fired. This will ensure that the document is ready to accept event bindings. See code below for an illustration. using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using System.Windows.Forms;
using ESRI.ArcGIS.Framework;
using ESRI.ArcGIS.esriSystem;
using ESRI.ArcGIS.Carto;
namespace BaseAddin {
public class BaseExt: ESRI.ArcGIS.Desktop.AddIns.Extension {
private static IActiveViewEvents_Event ViewEvents {
get { return ArcMap.Document.ActiveView as IActiveViewEvents_Event; }
}
public BaseExt() {
}
protected override void OnStartup() {
ArcMap.Events.OpenDocument += delegate() {
ViewEvents.SelectionChanged += SelectionChanged_Handler;
};
ArcMap.Events.NewDocument += delegate() {
ViewEvents.SelectionChanged += SelectionChanged_Handler;
};
}
private void SelectionChanged_Handler() {
MessageBox.Show("SelectionChanged");
}
}
}
... View more
06-01-2015
02:50 PM
|
0
|
0
|
1527
|
POST
|
I've just changed the extension setting from autoLoad="true" to autoLoad="false". Now when I open ArcMap, then go to Customize -> Extensions and select "Base Extension" it works as expected. However, when I close and re-open the app, the behaviour falls back to not firing the SelectionChanged event (or, as I imagine, not binding the event to the desired action).
... View more
06-01-2015
02:06 PM
|
0
|
3
|
1213
|
POST
|
Update: Changing target framework form 4.0 to 3.5 resolves the error described above, but I still do NOT get the message to show upon selecting features...
... View more
06-01-2015
01:45 PM
|
0
|
0
|
314
|
POST
|
No, it's should be a clean 10.1 install. I've also deleted all other add-ins so the only extension added is the one I'm testing. Thanks for your help, by the way. I've been pulling my hair over this for two days!
... View more
06-01-2015
12:37 PM
|
0
|
5
|
1213
|
POST
|
Sadly, this code crashes my ArcMap. In particular, line 28: Events.SelectionChanged += Events_SelectionChanged; doesn't allow ArcMap to start and instead displays a dialogue with "ArcGIS Desktop has encountered a serious application error and is unable to continue." Changing the code to ((IActiveViewEvents_Event)ArcMap.Document.ActiveView).SelectionChanged += delegate() {
MessageBox.Show("Selection Changed");
}; results in the same error. I am running ArcGIS Desktop 10.1 and matching Arcobjects .NET SDK.
... View more
06-01-2015
10:41 AM
|
0
|
8
|
1213
|
POST
|
I want to bind an action to the SelectionChanged event on the map. In the extension, I bind the action to the focused map's SelectionChanged event upon firing ArcMap.Events.NewDocument and ArcMap.Events.NewDocument. The assumption I'm making here is that upon firing of the New(Open)Document events, there is an active document with a map so I can indeed bind actions to its events. But it doesn't work. What is the correct way of getting this to work? using System;
using System.Collections.Generic;
using System.Text;
using System.IO;
using ESRI.ArcGIS.ArcMapUI;
using ESRI.ArcGIS.Carto;
namespace BaseAddin {
public class BaseExt: ESRI.ArcGIS.Desktop.AddIns.Extension {
public BaseExt() {
}
protected override void OnStartup() {
WireUpEvents();
}
private void WireUpEvents() {
ArcMap.Events.NewDocument += ArcMap_NewOpenDocument;
ArcMap.Events.OpenDocument += ArcMap_NewOpenDocument;
}
private void ArcMap_NewOpenDocument() {
IMxDocument doc = ArcMap.Document as IMxDocument;
((IActiveViewEvents_Event)doc.FocusMap).SelectionChanged +=
new IActiveViewEvents_SelectionChangedEventHandler(delegate() {
System.Windows.Forms.MessageBox.Show("Feature selection changed.");
});
}
}
}
... View more
06-01-2015
09:08 AM
|
0
|
12
|
6361
|
POST
|
Should it be possible to build an add-in using ArcObjects SDK for .NET 10.2 and deploy the add-in in ArcMap 10.1? I have just tried that and ArcMap 10.1 crashed. To give you some context, my dev machine runs ArcDesktop 10.2.2 but I'm developing extensions for an organisation that has ArcDestop 10.1 only. What is the best practice in such circumstances?
... View more
05-29-2015
09:05 AM
|
0
|
1
|
3632
|
POST
|
As a side note, I have tried to compile both with ticked and unticked Build option "Register for COM interop", I have tried to compile and register with admin rights, I have tried to remove and re-add reference to ESRI.ArcGIS.Desktop.AddIns... I have tried every single advice I could find on the web to resolve this and I'm obviously still missing something. Please help.
... View more
05-29-2015
05:15 AM
|
0
|
1
|
477
|
Online Status |
Offline
|
Date Last Visited |
11-11-2020
02:23 AM
|