|
POST
|
Hi everyone, I have a dozen mxds that I run during the night from Windows Task Scheduler. They start ArcMap automatically, run code to process some data and then shut down. Now I need to convert these from VBA to C# since VBA will no longer be supported at ArcGIS 10 and I am lost on how to start ArcMap, run code and lastly shut down ArcMap programmatically. I've seen a few post both here and the old forms on how to start ArcMap automatically but nothing on how to run code at start up. In the VBA code, there is code in the MxDocument_OpenDocument function to run the entire thing including shutdown. But in a standalone C# application, there is no such thing as MxDocument_OpenDocument so how do I get my code to run at start up? Thanks, Carlos
... View more
10-28-2010
06:01 AM
|
0
|
10
|
3142
|
|
POST
|
Vincent, The reason I wanted to have new instances of the same command is because my command takes in three parameters read in from a table. These parameters correspond to different datasets. My thinking was that I could have one command, create new instances of it, pass each instance the parameters it needs and then add each one of these to a menu/submenu. Is there a better way of doing this? I'm pretty new to C# programming so I am learning new stuff all the time. If you have another way, I'm all ears. You can see the code of this command in the message that Neil replied to. Thanks, Carlos Question for you: Do you really need to create a new instance of your command? Why just not pass same UID? It will be 2 input in menu bar, but it will call the same command. If your command do 2 differents operation, it's better to split this command in 2 distinct command. Else, juste add same UID in your commandItem. Vincent
... View more
08-19-2010
09:20 AM
|
0
|
0
|
334
|
|
POST
|
Dr. May, Thanks for the reply. We have our custom commands on a toolbar because the toolbar has a lot more things on it than just the Data menu/submenus/commands that I am trying to create dynamically. PLus, my boss wants everything on a toolbar so that users can just turn it on whenever they need to use the functionality we provide for them just like an ESRI or third-party toolbar. Also, the toolbar has over 20 customs tools as well and as far I know, tools must reside on a toolbar. Please correct me if I am wrong however. I am intrigued by your suggestion however, what do you mean by "create a window?"
... View more
08-19-2010
09:05 AM
|
0
|
0
|
1490
|
|
POST
|
I have been able to create menu items dynamically using ICommandItem and assigning them previously created custom commands with the code below but this approach does not seem to apply to a new instance of an existing command and I have no clue how to register the new instance. ICommandBar pSetEditMenu = pDataEditorMenu.CreateMenu("SetEditLayer", ref idx);
ICommandItem pSetEditItem = pSetEditMenu as ICommandItem;
pSetEditItem.Caption = "Set Edit Layer";
idx = 0;
pSetEditMenu.Add(MakeUID("RegGSS.Commands.CmdSetEditLayerScratchLine"), ref idx);
idx = 1;
pSetEditMenu.Add(MakeUID("RegGSS.Commands.CmdSetEditLayerScratchPoly"), ref idx);
internal static UID MakeUID(string id)
{
try
{
UID uid = new UIDClass();
uid.Value = id;
return uid;
}
catch (Exception ex)
{
ClsLogErrors.LogError(ex.StackTrace, ex.Message, "MakeUID", null);
MessageBox.Show("An error has occured." + "\r\n" + "The GIS group has been notified of this problem.", "Warning", MessageBoxButtons.OK, MessageBoxIcon.Information);
return null;
}
... View more
08-19-2010
04:31 AM
|
0
|
0
|
1490
|
|
POST
|
This produces the same error as before, "Value does not fall within the expected range." string className = dataReader.GetString(0);
idx = counter;
CmdTest2 cmdTest3 = new CmdTest2(entitySetName + " - " + className, entitySetName, className);
UID uid = new UID();
uid.Value = "RegGSS.cmdTest3";
pMenu.Add(uid, ref idx);
counter++; This produces a new error, "command not available." string className = dataReader.GetString(0);
idx = counter;
CmdTest2 cmdTest3 = new CmdTest2(entitySetName + " - " + className, entitySetName, className);
UID uid = new UID();
uid.Value = "{adc85ec2-c1c8-48ce-a975-1de2f0b393ff}";
pMenu.Add(uid, ref idx);
counter++; I don't think my second attempt is correct at all because the uid number is for the original command, CmdTest2, not the new instance, cmdTest3. Since adding an existing ArcGIS command and prexisting user created command (CmdTest2) works, it is starting to sound to me like you cannot create a new instance of a command and immediately add it to a menu but that too doesn't sound right. I messed with IMultiItem a bit too but could not get it working for my needs. Thanks again for your time and effort!
... View more
08-18-2010
10:19 AM
|
0
|
0
|
1490
|
|
POST
|
Vincent, Thanks for the reply. I've tried both: uid.Value = "RegGSS.cmdTest3"; and uid.Value = "{adc85ec2-c1c8-48ce-a975-1de2f0b393ff}"; which is the name of the command and the UID of it respectively but I still get the same error. hi, you must pass the command name or UID value to UID.value. example: uid.Value = "esriEditor.SaveEditsCommand"; or uid.Value = "{B479F48A-199D-11D1-9646-0000F8037368}"; ** you must replace B479F48A-199D-11D1-9646-0000F8037368 by your GUID command value Vincent
... View more
08-18-2010
08:46 AM
|
0
|
0
|
1490
|
|
POST
|
James, I was not able to get it to work with your suggestions but by pure trial and error, I was able to solve it. At one point, the code that populates the listbox, uses ITrackCancel to sort the results before displaying them in the listbox and when it hits that line of code, the cursor goes back to a pointer. Reissung pMouseCursor.SetCursor(2); right afterwards resets the cursor back to the hourglass for the duration of the code. The cursor does briefly (a second or two) switches to the pointer between the two lines of code but that's fine. Yes, I am in the West Palm office off Gun Club road. Did you work at the District in the past? Your name does sound familiar to me for some reason. I've been here since 1988. Anyhow, thanks for your time and your help. As always, I appreciate it a lot!!! Carlos No problem at all. Any new major switch is going to cause disruptions, and I think this forum has a ways to go to get at the activity levels seen in previous versions --- it's just a part of making major changes like this I guess. Please post up your solution when you find it! I know what I have posted does work for many of the apps I have implemented and currently maintain (all are VB.NET framwork 3.5/ ArcGIS 9.3.1), so I'd like to hear if you found another way to accomplish this. {Also: are you in the West Palm Beach office off of Gun Club Rd? I'm originally from Lantana (Palm Beach County) and return quite often to visit family and freinds --- I've been residing in Charlotte County since 1999} Take Care, james
... View more
08-18-2010
05:00 AM
|
0
|
0
|
706
|
|
POST
|
Hi everyone, From an existing custom menu on a custom toolbar called Data, I am trying to create a structure like this and do it all on the fly at run time: Menu1
|
|----Submenu1
| |----Command1
| |----Command2
|----Submenu2
| |----Command1
| |----Command2
|----Submenu3 Thanks to LOTS of help from the forums, I have been able to create the menus and sub-menus on the fly with no problems but now I am stuct trying to do the same with the commands. In the example above, if I add an existing ArcMap or custom command previously created to Command1 in Submenu1, the code works fine. If I try to add a new instance of an existing command, the code crashes trying to give it a new UID with an error of, "Value does not fall within the expected range." internal static void PopulateDataSubMenu(ICommandBar pMenu, string entitySetName)
{
try
{
OleDbConnection dataConnection = new OleDbConnection();
dataConnection.ConnectionString = "Provider=Microsoft.Jet.OLEDB.4.0;" +
"Data Source=\\\\ad.sfwmd.gov\\dfsroot\\data\\err_gis\\applications\\dev\\mdb\\rimGISLibDatabase\\mdb\\GISLIBFeaterClassName1.mdb";
dataConnection.Open();
OleDbCommand dataCommand = new OleDbCommand();
dataCommand.Connection = dataConnection;
dataCommand.CommandText = "SELECT distinct(Order1ClassName) " +
"FROM qryorder1 " +
"WHERE Order1SetName = '" + entitySetName + "'";
OleDbDataReader dataReader = dataCommand.ExecuteReader();
object idx = 0;
int counter = 0;
while (dataReader.Read())
{
string className = dataReader.GetString(0);
idx = counter;
CmdTest2 cmdTest3 = new CmdTest2(entitySetName + " - " + className, entitySetName, className);
UID uid = new UIDClass();
uid.Value = cmdTest3; <---CRASH HERE
pMenu.Add(uid, ref idx);
counter++;
}
dataReader.Close();
dataConnection.Close();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
} In the code above, CmdTest2 is a command created using the ESRI BaseCommand template and I am passing it a couple of parameters so that I can use the same command to load different datasets. Does anyone know how what is going on and how I can fix this? Thanks, Carlos
... View more
08-18-2010
04:48 AM
|
0
|
11
|
2307
|
|
POST
|
Thanks for the reply James and my apologies for replying so late. The new forums is not notifying me of when I get a new message in spite of me setting it to send email immediately so if I forget to check for new messages myself, I don't see them and in this case, I got pulled away from this problem to take care of another one. 😞 Anyhow, I will give your suggestion a try. Carlos Carlos, Have you tried to implement the cursor from the parent Windows form? Prior to the method call, set the cursor (VB.NET): Windows.Forms.Cursor.Current = Cursors.WaitCursor After the method and the return to the form, re-set the cursor: Windows.Forms.Cursor.Current = Cursors.Arrow Hope this helps, james
... View more
08-17-2010
07:02 AM
|
0
|
0
|
706
|
|
POST
|
Hi everyone, I have a form which has a listbox on it displaying all lakes in the state so the user can select which one they want to load and zoom to. On the InitializeComponent(); section of a C# form, I set the mouse cursor to an hourglass with this code: IMouseCursor pMouseCursor = new MouseCursorClass();
pMouseCursor.SetCursor(2); Right after this line, the code calls another method which queries the lakes layer, puts all of the names into an array and returns this to the listbox for display. As soon as the code goes to the method that does the query, the cursor returns to the pointer instead of staying an hourglass. Trying to set the cursor back to hourglass inside of this query method has no effect. This query can sometimes take up to a minute to run depending on network traffic so I definitely want to show the user that code is running and not have them think the program is locked up. Any ideas on how to fix this? Thanks, Carlos
... View more
08-12-2010
04:41 AM
|
0
|
5
|
2174
|
|
POST
|
Dr. May, Thanks for the reply. I don't think you missed anything in my question, I think maybe I'm not understanding how to use IMenuDef properly. All of the examples I've seen, always show things hardcoded for the number of menus and I can't seem to figure out how to code this to happen dynamically. I thought about going the extension way but am at a loss on how to even get started with it beyond creating the extension. I will try to apply what you suggest. If you have any examples on how to create menus dynamically, I would be greatful if you could share them with me. Thanks for your time, Carlos
... View more
08-11-2010
10:05 AM
|
0
|
0
|
474
|
|
POST
|
Hi everyone, My boss would like to automate the creation of menus, commands and forms dynamically in C#. We have a custom toolbar with lots of menus and submenus on them. On these, there are commands, tools, etc. My boss would like to read a database table and create a new menu for each row in the table, i.e. buildings, roads, canals, etc. Each one of these menus would have either submenus, forms, commands or tools on it. So far, I have been able to manually create a generic form and populate it (add checkbox controls) with different types of data. My problem now is creating the menus themselves dynamically every time the toolbar is displayed. I have experimented with IMenuDef but from what I can see, you must know how many options (submenus) you are going to have and I will not know that at runtime. My boss wants to be able to edit the database table and have the new menus, forms, tools, etc. magically appear on the toolbar. I've read tons of postings on the forums and I get the suspicion that it is possible to do it, but I cannot figure it out. Any help is greatly appreciated! Carlos
... View more
08-10-2010
01:37 PM
|
0
|
4
|
1475
|
|
POST
|
Hi everyone, I am trying to write some generic C# code that will identify the data source of any possible layer a user might add (Coverage, Shapefile, table, etc.). I thought I had the solution when I found the ESRI IDataLayer Example and this works well in VB6 or VBA. When I convert it to C# however, it fails for layers of type SDE Raster, Raster Catalog and File System Raster. pDatasetName becomes null with these data types and the code crashes. So far in my testing I have determined that I can use IDataLayer2::DataSourceName::NameString for data types of: File System Raster, SDE Raster, ArcGIS Image Service, Raster Catalog, Coverage Feature Class and IDatasetName2::Name for data types of: Shapefile Feature Class, Personal Geodatabase Feature Class, File Geodatabase Feature Class. While this approach works, I do not want to have to write code for every possibility, i.e. if (pLayer is IFeatureLayer) { do something } else if (pLayer is IRasterLayer) { do something } IMxDocument pMxDocument = (IMxDocument)m_application.Document;
IMap pMap = pMxDocument.FocusMap;
ILayer pLayer = pMap.get_Layer(0) as ILayer;
IDataLayer2 pDataLayer = pLayer as IDataLayer2;
IDatasetName2 pDatasetName = pDataLayer.DataSourceName as IDatasetName2;
IWorkspaceName pWorkspaceName = pDatasetName.WorkspaceName;
string name = string.Empty;
if (pDatasetName is IFeatureClassName)
{
IFeatureClassName pFeatureClassName = pDatasetName as IFeatureClassName;
if (pFeatureClassName.FeatureDatasetName != null)
{
name = pFeatureClassName.FeatureDatasetName.Name;
}
}
MessageBox.Show("Path: " + pWorkspaceName.PathName);
MessageBox.Show("Feature Dataset: " + name);
MessageBox.Show("Feature Class/Dataset: " + pDatasetName.Name);
... View more
07-13-2010
07:15 AM
|
0
|
0
|
880
|
|
POST
|
I had not considered the possibility that the user might add additional frames. I've never used a MapFrames's IElementProperties.CustomProperty so I will see if I can get that working. Thanks again! Keep in mind a document can have more than one map,. An IExtension could listen for newly added mapframes and initialize a new layer listener when a new map is added. The extension could manage a list of listeners (one for each map in the document). Or it might be easier to just put it in the MapFrames's IElementProperties.CustomProperty, but I'd test to make sure objects are destroyed gracefully when mapframes are deleted. http://forums.esri.com/Thread.asp?c=93&f=993&t=246221&mc=2#752174
... View more
07-06-2010
09:14 AM
|
0
|
0
|
851
|
|
POST
|
Thanks James, This is pretty much the code I currently have in my extension. Looks like this will be my best option to catch something being added regardless of the source, Add Data, ArcCatalog, etc. Carlos, This works for me in my class that implements ICommand/IToolControl... Also, it works if the user clicks the Add Data button or drops a layer into the TOC from ArcCatalog. Public Class BFETools
Implements ESRI.ArcGIS.SystemUI.ICommand
Implements ESRI.ArcGIS.SystemUI.IToolControl
Private m_pApp As IApplication
Private WithEvents m_pActiveViewEvents As ESRI.ArcGIS.Carto.Map
'as normally, you will set your IApplication in your OnCreate Sub
Private Sub m_pActiveViewEvents_ItemAdded(ByVal Item As Object) Handles m_pActiveViewEvents.ItemAdded
Dim pMxDoc As IMxDocument = m_pApp.Document
Dim pLayer As IFeatureLayer
pLayer = pMxDoc.FocusMap.Layer(0)
MsgBox(pLayer.Name & " has been Added")
End Sub
... View more
07-06-2010
09:12 AM
|
0
|
0
|
851
|
| Title | Kudos | Posted |
|---|---|---|
| 1 | 02-11-2016 06:06 AM | |
| 1 | 08-07-2015 10:13 AM | |
| 2 | 06-29-2015 12:45 PM |
| Online Status |
Offline
|
| Date Last Visited |
11-11-2020
02:23 AM
|