I'm creating a utility to run in ArcGIS for Desktop using ArcObjects (9.3.1 SDK) and C#.Net. My prototype involves a toolbar with two comboboxes and a tool. The first combo selects a layer in the TOC, and the second selects a field from the selected layer. The tool will be used to interact with the map.

Basically I want to select a layer, select a valid field, then click a feature in the map and get its value for the chosen field. Here's an image of the toolbar, if it helps:

[question almost entirely re-worded from here down]

The problem I am having is passing state between the native COM UI parts and my custom .Net controls. For example, I want to catch the DropDownClosed event on the Layer combobox, assemble a valid list of columns relative to that layer, then apply the list of field names (via IFields) to the Fields combobox.

After applying some the initial comments by RagiYaserBurham and blah238, and merging them with details from this page, the following DropDownClosed event handler does go from the combobox back to the toolbar (ICommandBar), but I don't understand how to cast from ICommandItem back to my implementation of the Fields combobox in a UserControl:

This is still a dirty testbed (hence AngryToolbar). But the solution shows how to start from an extended UserControl that implements ICommand and IToolControl and drill back down to a .Net component. I really appreciate the assistance of everyone who offered suggestions. Thanks so much. :)

How about making your layerName variable public static scope?
–
artwork21Mar 12 '12 at 17:12

@artwork21, that sounds good, but I'm still not sure how to access the instance of either combobox from its counterpart on the toolbar? Know what I mean? I suspect it's a simple fundamental thing I'm just not aware of.
–
elrobisMar 12 '12 at 17:29

This sounds like a different question. I'm not clear why you need to do that. It seems to me the Fields combobox should be cleared and repopulated based on the Layer combo. The Layer combobox should be populated based on the document event listener.
–
Rich WawrzonekMar 12 '12 at 17:44

@RichWawrzonek that is exactly right. But I'm not sure how to get to the existing instance of the Fields combo from the Layers combo.. For that matter, the tool needs to read both of their values.
–
elrobisMar 12 '12 at 17:50

3 Answers
3

As I understand it, you have two .NET ComboBoxes on a UserControl that implements ICommand and IToolControl, and you want to get a reference to one of the combo boxes from the other. As long as they are in the same scope you should just be able to refer to them by their variable names (check your UserControl designer for the names of your controls).

If the two combo boxes are on separate UserControls, then try casting ICommandItem.Command to your other UserControl.

Bingo. This line did the trick to get from the instance of ICommandItem back into the UserControl class I implemented: FieldSelectUC fs = fieldsItem.Command as FieldSelectUC; I can now see all it's props in the debugger. Tremendous thanks to you.
–
elrobisMar 12 '12 at 23:11

Hooray! I've been using add-ins exclusvely for a while so I had to dig through some old stuff to remember how it all worked :) This kind of thing is much easier (though admittedly less flexible) with add-ins in 10 since there is a specific ComboBox type and you can just refer to other add-in components with static variables and methods.
–
blah238Mar 12 '12 at 23:16

1

Yup, it definitely seemed easier through the new add-ins. In researching this I found add-ins this and add-ins that but they just weren't available to my implementation. The GraphicsLayerToolControl example in the .Net help (on my system that address is C:\Program Files (x86)\ArcGIS\DeveloperKit\SamplesNET\Desktop\GraphicsLayerToolControl\CSharp\Gra‌​phicsLayerToolControl2008.sln) that helped me get going with the UserControl and events stuff, but I just couldn't figure out how to punch a hole through to .Net from the COM control. I can't exaggerate how thankful I am. Sincerely.
–
elrobisMar 12 '12 at 23:31

Whenever I do this sort of thing I store the layer and field names in a static property set contained in the toolbar. Then I use a document event handler to check if layers are added/removed from ArcMap or if the document is changed.
The layer and field properties get updated whenever they are changed in the drop-down by the user. If the layer is removed from ArcMap or the document is closed they are reset to null. Then you can just check for null values before your program runs.

+1 you make it sound so easy. :) But the problem I have is accessing the properties of an already instantiated control from the point of view of any other control. I like your idea of putting their shared properties on the toolbar, could you update your answer to show how I can actually read the properties of the containing toolbar from the point of view of one of the comboboxes? 'Cos that's basically what I'm after. I already know how to use document events to listen for changes to the TOC, so I don't need help with that aspect. Thanks for your response.
–
elrobisMar 12 '12 at 17:46

Ragi is right. Since you are using COM toolbar you can just pass the uid of your combobox to the ICommandBar.Find method to get a reference. His link explains it all.
–
Rich WawrzonekMar 12 '12 at 18:40

I like Ragi's idea too. There is something fundamental I am missing, though. For instance, this line returns a null toolbar (where this is a UserControl with label and combobox): ICommandBar toolbar = this.Parent as ICommandBar; It's this sort of fundamental UI object traversal that is killing me. I don't know how to get back to the toolbar to implement either of your suggestions. (And actually i like the idea of these vars on the toolbar a little better. I'd probably do it by adding a public getter to the toolbar that applies Ragi's idea). Thanks for your continued help.
–
elrobisMar 12 '12 at 18:45

2

I don't think this.Parent is valid for COM interfaces -- that is a .NET/Windows Forms concept. You don't want to "traverse the UI", you want to access your ICommands by their IDs.
–
blah238Mar 12 '12 at 19:15

I had a similar problem with a custom tool. I have a custom form which gets opened by a button on an AddIn-Toolbar in ArcGis 10.x. On this form there is a button that should retreive the coordinates of a click in the map, snapping included.
I could start the tool and handle the click in the map, but I could not get the value back to my form, because the cast to the custom-tool always failed.
The solution was to use AddIn from ESRI.ArcGIS.Desktop.AddIns. With this it was easy to get access to every property and methode of my custom tool.
ESRIs documentation resides here: http://resources.arcgis.com/en/help/arcobjects-net/conceptualhelp/index.html#/Add_in_coding_patterns/0001000000zz000000/

Here is the code-snippet from the OnClick-Event of the button on the custom form: