private SubscriptionToken _eventToken = null; // Called when the visibility of the DockPane changes. protectedoverridevoidOnShow(bool isVisible) { if (isVisible && _eventToken == null) //Subscribe to event when dockpane is visible { _eventToken = MapSelectionChangedEvent.Subscribe(OnMapSelectionChangedEvent); }
if (!isVisible && _eventToken != null) //Unsubscribe as the dockpane closes. { MapSelectionChangedEvent.Unsubscribe(_eventToken); _eventToken = null; } } //Event handler when the MapSelection event is triggered. privatevoidOnMapSelectionChangedEvent(MapSelectionChangedEventArgs obj) { MessageBox.Show("Selection has changed"); }
执行命令
1 2 3 4 5
IPlugInWrapper wrapper = FrameworkApplication.GetPlugInWrapper("esri_editing_ShowAttributes"); var command = wrapper as ICommand; // tool and command(Button) supports this
if ((command != null) && command.CanExecute(null)) command.Execute(null);
设置当前工具
1 2 3 4 5 6 7
// use SetCurrentToolAsync FrameworkApplication.SetCurrentToolAsync("esri_mapping_selectByRectangleTool");
// or use ICommand.Execute ICommand cmd = FrameworkApplication.GetPlugInWrapper("esri_mapping_selectByRectangleTool") as ICommand; if ((cmd != null) && cmd.CanExecute(null)) cmd.Execute(null);
// Define the condition in the DAML file based on the state if (activate) FrameworkApplication.State.Activate("someState"); else FrameworkApplication.State.Deactivate("someState");
确定应用程序是否繁忙
1 2 3 4 5 6 7
// The application is considered busy if a task is currently running on the main worker thread or any // pane or dock pane reports that it is busy or intiializing.
// Many Pro styles (such as Esri_SimpleButton) ensure that a button is disabled when FrameworkApplication.IsBusy is true // You would use this property to bind to the IsEnabled property of a control (such as a listbox) on a dockpane or pane in order // to disable it from user interaction while the application is busy. bool isbusy = FrameworkApplication.IsBusy;
// center it Rect rect = System.Windows.SystemParameters.WorkArea; FrameworkApplication.Current.MainWindow.Left = rect.Left + (rect.Width - FrameworkApplication.Current.MainWindow.ActualWidth) / 2; FrameworkApplication.Current.MainWindow.Top = rect.Top + (rect.Height - FrameworkApplication.Current.MainWindow.ActualHeight) / 2;
关闭 ArcGIS Pro
1
FrameworkApplication.Close();
获取 ArcGIS 专业版
1 2 3
//"GetEntryAssembly" should be ArcGISPro.exe string version = System.Reflection.Assembly.GetEntryAssembly() .GetName().Version.ToString();
关闭特定窗格
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
string _viewPaneID = "my pane"; //DAML ID of your pane //You could have multiple instances (InstanceIDs) of your pane. //So you can iterate through the Panes to get "your" panes only IList<uint> myPaneInstanceIDs = new List<uint>(); foreach (Pane pane in FrameworkApplication.Panes) { if (pane.ContentID == _viewPaneID) { myPaneInstanceIDs.Add(pane.InstanceID); //InstanceID of your pane, could be multiple, so build the collection } } foreach (var instanceID in myPaneInstanceIDs) //close each of "your" panes. { FrameworkApplication.Panes.ClosePane(instanceID); }
激活窗格
1 2 3 4 5 6 7 8 9
var mapPanes = ProApp.Panes.OfType<IMapPane>(); foreach (Pane pane in mapPanes) { if (pane.Caption == "MyMap") { pane.Activate(); break; } }
// determine dockpane state DockPaneState state = pane.DockState;
// pin it pane.Pin();
// hide it pane.Hide();
码头窗格撤消/重做
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
// in order to find a dockpane you need to know it's DAML id var pane = FrameworkApplication.DockPaneManager.Find("esri_core_contentsDockPane");
// get the undo stack OperationManager manager = pane.OperationManager; if (manager != null) { // undo an operation if (manager.CanUndo) await manager.UndoAsync();
// redo an operation if (manager.CanRedo) await manager.RedoAsync();
// clear the undo and redo stack of operations of a particular category manager.ClearUndoCategory("Some category"); manager.ClearRedoCategory("Some category"); }
查找停靠窗格并获取其视图模型
1 2 3 4 5 6 7 8 9 10 11 12
// in order to find a dockpane you need to know it's DAML id.
// Here is a DAML example with a dockpane defined. Once you have found the dockpane you can cast it // to the dockpane viewModel which is defined by the className attribute. // //<dockPanes> // <dockPane id="MySample_Dockpane" caption="Dockpane 1" className="Dockpane1ViewModel" dock="bottom" height="5"> // <content className="Dockpane1View" /> // </dockPane> //</dockPanes>
Dockpane1ViewModel vm = FrameworkApplication.DockPaneManager.Find("MySample_Dockpane") as Dockpane1ViewModel;
打开“后台”选项卡
1 2
//Opens the Backstage to the "About ArcGIS Pro" tab. FrameworkApplication.OpenBackstage("esri_core_aboutTab");
访问当前主题
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
//Gets the application's theme var theme = FrameworkApplication.ApplicationTheme; //ApplicationTheme enumeration if (FrameworkApplication.ApplicationTheme == ApplicationTheme.Dark) { //Dark theme }
if (FrameworkApplication.ApplicationTheme == ApplicationTheme.HighContrast) { //High Contrast } if (FrameworkApplication.ApplicationTheme == ApplicationTheme.Default) { //Light/Default theme }
privatevoidChangeCaptionImage() { IPlugInWrapper wrapper = FrameworkApplication.GetPlugInWrapper("MyAddin_MyCustomButton"); if (wrapper != null) { wrapper.Caption = "new caption";
// ensure that T-Rex16 and T-Rex32 are included in your add-in under the images folder and have // BuildAction = Resource and Copy to OutputDirectory = Do not copy wrapper.SmallImage = BuildImage("T-Rex16.png"); wrapper.LargeImage = BuildImage("T-Rex32.png"); } }
//Pass in the daml id of your button. Or pass in any Pro button ID. IPlugInWrapper wrapper = FrameworkApplication.GetPlugInWrapper("button_id_from daml"); var buttonTooltipHeading = wrapper.TooltipHeading;
publicasync Task Progressor_NonCancelable() { ArcGIS.Desktop.Framework.Threading.Tasks.ProgressorSource ps = new ArcGIS.Desktop.Framework.Threading.Tasks.ProgressorSource("Doing my thing...", false);
int numSecondsDelay = 5; //If you run this in the DEBUGGER you will NOT see the dialog await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => Task.Delay(numSecondsDelay * 1000).Wait(), ps.Progressor); }
publicasync Task Progressor_Cancelable() { ArcGIS.Desktop.Framework.Threading.Tasks.CancelableProgressorSource cps = new ArcGIS.Desktop.Framework.Threading.Tasks.CancelableProgressorSource("Doing my thing - cancelable", "Canceled");
int numSecondsDelay = 5; //If you run this in the DEBUGGER you will NOT see the dialog
//simulate doing some work which can be canceled await ArcGIS.Desktop.Framework.Threading.Tasks.QueuedTask.Run(() => { cps.Progressor.Max = (uint)numSecondsDelay; //check every second while (!cps.Progressor.CancellationToken.IsCancellationRequested) { cps.Progressor.Value += 1; cps.Progressor.Status = "Status " + cps.Progressor.Value; cps.Progressor.Message = "Message " + cps.Progressor.Value;
if (System.Diagnostics.Debugger.IsAttached) { System.Diagnostics.Debug.WriteLine(string.Format("RunCancelableProgress Loop{0}", cps.Progressor.Value)); } //are we done? if (cps.Progressor.Value == cps.Progressor.Max) break; //block the CIM for a second Task.Delay(1000).Wait();
//Set the tool's loadOnClick attribute to "false" in the config.daml. //This will allow the tool to be created when Pro launches, so that the disabledText property can display customized text at startup. //Remove the "condition" attribute from the tool. Use the OnUpdate method(below) to set the enable\disable state of the tool. //Add the OnUpdate method to the tool. //Note: since OnUpdate is called very frequently, you should avoid lengthy operations in this method //as this would reduce the responsiveness of the application user interface. internalclassSnippetButton : ArcGIS.Desktop.Framework.Contracts.Button { protectedoverridevoidOnUpdate() { bool enableSate = true; //TODO: Code your enabled state bool criteria = true; //TODO: Evaluate criteria for disabledText
if (enableSate) { this.Enabled = true; //tool is enabled } else { this.Enabled = false; //tool is disabled //customize your disabledText here if (criteria) this.DisabledTooltip = "Missing criteria 1"; } } }
publicstaticvoidExampleUsage() { //Image 'Dino32.png' is added as Build Action: Resource, 'Do not copy' var img = ForImage("Dino32.png"); //Use the image... }
// There are two ways to prevent ArcGIS Pro from closing // 1. Override the CanUnload method on your add-in's module and return false. // 2. Subscribe to the ApplicationClosing event and cancel the event when you receive it
internalclassModule1 : Module {
// Called by Framework when ArcGIS Pro is closing protectedoverrideboolCanUnload() { //return false to ~cancel~ Application close returnfalse; }
// cref: ARCGIS.DESKTOP.CORE.EVENTS.PROJECTOPENEDEVENT // cref: ARCGIS.DESKTOP.CORE.EVENTS.PROJECTOPENEDEVENT.SUBSCRIBE // cref: ARCGIS.DESKTOP.CORE.EVENTS.PROJECTOPENEDEVENT.UNSUBSCRIBE // cref: ARCGIS.DESKTOP.FRAMEWORK.CONTRACTS.MODULE.INITIALIZE // cref: ARCGIS.DESKTOP.FRAMEWORK.CONTRACTS.MODULE.UNINITIALIZE #region How to determine when a project is opened protectedoverrideboolInitialize() //Called when the Module is initialized. { ProjectOpenedEvent.Subscribe(OnProjectOpened); //subscribe to Project opened event returnbase.Initialize(); }
privatevoidOnProjectOpened(ProjectEventArgs obj) //Project Opened event handler { MessageBox.Show($"{Project.Current} has opened"); //show your message box }
protectedoverridevoidUninitialize() //unsubscribe to the project opened event { ProjectOpenedEvent.Unsubscribe(OnProjectOpened); //unsubscribe return; }
publicProSnippetMapTool() { //Set the MapTool base class' OverlayControlID to the DAML id of your embeddable control in the constructor this.OverlayControlID = "ProAppModule1_EmbeddableControl1"; }
protectedoverride Task HandleMouseDownAsync(MapViewMouseButtonEventArgs e) { return QueuedTask.Run(() => { //assign the screen coordinate clicked point to the MapTool base class' OverlayControlLocation property. this.OverlayControlPositionRatio = e.ClientPoint;
}); }
激活选项卡时命令搜索中建议的命令选项。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
//In the module class.. publicoverridestring[] GetSuggestedCMDIDs(string activeTabID) { //Return the static list of daml ids you want to be the (suggested) //defaults relevant to the given tab. It can be none, some, or all of the //commands associated with the activeTabID. //In this example, there are two tabs. This example arbitrarily //identifies just one command on each tab to be a default to show in the //command search list (when _that_ particular tab is active) switch (activeTabID) { case"CommandSearch_Example_Tab1": returnnewstring[] { "CommandSearch_Example_Button2" }; case"CommandSearch_Example_Tab2": returnnewstring[] { "CommandSearch_Example_Button4" }; } returnnewstring[] { "" }; }