-
Notifications
You must be signed in to change notification settings - Fork 119
ProSnippets Framework
Language: C#
Subject: Framework
Contributor: ArcGIS Pro SDK Team <[email protected]>
Organization: Esri, http://www.esri.com
Date: 11/7/2025
ArcGIS Pro: 3.6
Visual Studio: 2022
IPlugInWrapper wrapper = FrameworkApplication.GetPlugInWrapper("esri_editing_ShowAttributes");
// tool and command(Button) supports this
if (wrapper is ICommand command && command.CanExecute(null))
command.Execute(null);// 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 initializing.
// 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;Window window = Application.Current.MainWindow;
// center it
Rect rect = SystemParameters.WorkArea;
Application.Current.MainWindow.Left = rect.Left + (rect.Width - Application.Current.MainWindow.ActualWidth) / 2;
Application.Current.MainWindow.Top = rect.Top + (rect.Height - Application.Current.MainWindow.ActualHeight) / 2;// use SetCurrentToolAsync with await
FrameworkApplication.SetCurrentToolAsync("esri_mapping_selectByRectangleTool").Wait();
// or use ICommand.Execute
if (FrameworkApplication.GetPlugInWrapper("esri_mapping_selectByRectangleTool") is ICommand cmd && cmd.CanExecute(null))
cmd.Execute(null);FrameworkApplication.ActivateTab("esri_mapping_insertTab");// Define the condition in the DAML file based on the state
if (activate)
FrameworkApplication.State.Activate("someState");
else
FrameworkApplication.State.Deactivate("someState");// 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 initializing.
// 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;Window window = Application.Current.MainWindow;
// center it
Rect rect = SystemParameters.WorkArea;
Application.Current.MainWindow.Left = rect.Left + (rect.Width - Application.Current.MainWindow.ActualWidth) / 2;
Application.Current.MainWindow.Top = rect.Top + (rect.Height - Application.Current.MainWindow.ActualHeight) / 2;FrameworkApplication.Close();string version = System.Reflection.Assembly.GetEntryAssembly()
.GetName().Version.ToString();double left = 250; //Window's left edge, in relation to the desktop
double top = 150; //Window's top edge, in relation to the desktop
var myProwindow = new ProWindow();
myProwindow.WindowStartupLocation = System.Windows.WindowStartupLocation.Manual;
myProwindow.Left = left;
myProwindow.Top = top;
//MetroWindows remember their last location unless SaveWindowPosition is set to
//false.
myProwindow.SaveWindowPosition = false;
myProwindow.Owner = FrameworkApplication.Current.MainWindow;
myProwindow.Closed += (o, e) => { myProwindow = null; };
myProwindow.Show();
//uncomment for modal
//myProwindow.ShowDialog();//Image 'Dino32.png' is added as Build Action: Resource, 'Do not copy'
var img = ForImage("Dino32.png");
//Use the image...
static BitmapImage ForImage(string imageName)
{
return new BitmapImage(PackUriForResource(imageName));
}
static Uri PackUriForResource(string resourceName, string folderName = "Images")
{
string asm = System.IO.Path.GetFileNameWithoutExtension(
System.Reflection.Assembly.GetExecutingAssembly().Location);
string uriString = folderName.Length > 0
? string.Format("pack://application:,,,/{0};component/{1}/{2}", asm, folderName, resourceName)
: string.Format("pack://application:,,,/{0};component/{1}", asm, resourceName);
return new Uri(uriString, UriKind.Absolute);
}// 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
// 1. Override the CanUnload method on your add-in's module and return false.
// Called by Framework when ArcGIS Pro is closing
{
//return false to ~cancel~ Application close
}
{
// 2. Subscribe to the ApplicationClosing event and cancel the event when you receive it
// Replace this line:
// ArcGIS.Desktop.Framework.Events.ApplicationClosingEvent.Subscribe(() => { });
// With the following, which matches the required delegate signature:
ArcGIS.Desktop.Framework.Events.ApplicationClosingEvent.Subscribe((args) =>
{
//Do something here, e.g. prompt user to save work
return Task.CompletedTask;
}
);
// in the Application Closing event handler set the Cancel property of the event args to true to prevent Pro from closing
}
}
// Called by Framework when ArcGIS Pro is closing
{
ArcGIS.Desktop.Framework.Events.ApplicationClosingEvent.Subscribe((args) =>
{
//Do something here, e.g. prompt user to save work
return Task.CompletedTask;
}
);// override the Initialize and Uninitialize methods of your add-in's module to subscribe and unsubscribe to the ProjectOpenedEvent
ProjectOpenedEvent.Subscribe(OnProjectOpened); //subscribe to Project opened event
ProjectOpenedEvent.Unsubscribe(OnProjectOpened); //unsubscribe from the event as the module is unloaded
void OnProjectOpened(ProjectEventArgs obj) //Project Opened event handler
{
MessageBox.Show($"{Project.Current} has opened"); //show your message box
}//In the module class..
//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":
result = ["CommandSearch_Example_Button2"];
break;
case "CommandSearch_Example_Tab2":
result = ["CommandSearch_Example_Button4"];
break;
}
result = [""]; // Default caseList<uint> myPaneInstanceIDs = [];
foreach (Pane p in FrameworkApplication.Panes)
{
if (p.ContentID == paneID)
{
myPaneInstanceIDs.Add(p.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);
}var mapPanes = FrameworkApplication.Panes.OfType<IMapPane>();
foreach (Pane p in mapPanes.Cast<Pane>())
{
if (p.Caption == paneID)
{
p.Activate();
break;
}
}// in order to find a dockpane you need to know its DAML id
var pane = FrameworkApplication.DockPaneManager.Find(dockPaneID);// in order to find a dockpane you need to know its DAML id
pane = FrameworkApplication.DockPaneManager.Find(dockPaneID);
// determine visibility
bool visible = pane.IsVisible;
// activate it
pane.Activate();
// determine dockpane state
DockPaneState state = pane.DockState;
// pin it
pane.Pin();
// hide it
pane.Hide();// in order to find a dockpane you need to know its DAML id
pane = FrameworkApplication.DockPaneManager.Find(dockPaneID);
// get the undo stack
OperationManager manager = pane.OperationManager;
if (manager != null)
{
// undo an operation
// Use await with UndoAsync and RedoAsync
if (manager.CanUndo)
manager.UndoAsync().Wait();
// redo an operation
if (manager.CanRedo)
manager.RedoAsync().Wait();
// clear the undo and redo stack of operations of a particular category
manager.ClearUndoCategory("Some category");
manager.ClearRedoCategory("Some category");
}// 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>
DockpaneViewModel vm = FrameworkApplication.DockPaneManager.Find(dockPaneID) as DockpaneViewModel;var addin_infos = FrameworkApplication.GetAddInInfos();
StringBuilder sb = new();
foreach (var info in addin_infos)
{
if (info == null)
break;//no add-ins probed
sb.AppendLine($"Addin: {info.Name}");
sb.AppendLine($"Description {info.Description}");
sb.AppendLine($"ImagePath {info.ImagePath}");
sb.AppendLine($"Author {info.Author}");
sb.AppendLine($"Company {info.Company}");
sb.AppendLine($"Date {info.Date}");
sb.AppendLine($"Version {info.Version}");
sb.AppendLine($"FullPath {info.FullPath}");
sb.AppendLine($"DigitalSignature {info.DigitalSignature}");
sb.AppendLine($"IsCompatible {info.IsCompatible}");
sb.AppendLine($"IsDeleted {info.IsDeleted}");
sb.AppendLine($"TargetVersion {info.TargetVersion}");
sb.AppendLine($"ErrorMsg {info.ErrorMsg}");
sb.AppendLine($"ID {info.ID}");
sb.AppendLine("");
}
System.Diagnostics.Debug.WriteLine(sb.ToString());
MessageBox.Show(sb.ToString(), "Addin Infos");//Opens the Backstage to the "About ArcGIS Pro" tab.
FrameworkApplication.OpenBackstage("esri_core_aboutTab");//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
}ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show("Some Message", "Some title", MessageBoxButton.YesNo, MessageBoxImage.Information, MessageBoxResult.Yes);Notification notification = new()
{
Title = FrameworkApplication.Title,
Message = "Notification 1",
ImageSource = Application.Current.Resources["ToastLicensing32"] as ImageSource
};
FrameworkApplication.AddNotification(notification);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;
wrapper.LargeImage = buildImage2;
}//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.
{
bool enableState = true; //TODO: Code your enabled state
bool criteria = true; //TODO: Evaluate criteria for disabledText
if (enableState)
{
Enabled = true; //tool is enabled
}
else
{
Enabled = false; //tool is disabled
//customize your disabledText here
if (criteria)
DisabledTooltip = "Missing criteria 1";
}
}//Pass in the id of your button. Or pass in any Pro button ID.
IPlugInWrapper wrapper = FrameworkApplication.GetPlugInWrapper(proButtonID);
var buttonTooltipHeading = wrapper.TooltipHeading;ArcGIS.Desktop.Framework.Events.ActiveToolChangedEvent.Subscribe((args) =>
{
string prevTool = args.PreviousID;
string newTool = args.CurrentID;
});ArcGIS.Desktop.Framework.Events.ActiveToolChangedEvent.Unsubscribe((args) =>
{
string prevTool = args.PreviousID;
string newTool = args.CurrentID;
});ProgressorSource ps = new("Doing my thing...", false);
int numSecondsDelay = 5;
//If you run this in the DEBUGGER you will NOT see the dialog
QueuedTask.Run(() => Task.Delay(numSecondsDelay * 1000).Wait(), ps.Progressor);CancelableProgressorSource cps =
new("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
// Use await with QueuedTask.Run
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();
}
System.Diagnostics.Debug.WriteLine(string.Format("RunCancelableProgress: Canceled {0}",
cps.Progressor.CancellationToken.IsCancellationRequested));
}, cps.Progressor);public ProSnippetMapTool()
{
//Set the MapTool base class' OverlayControlID to the DAML id of your embeddable control in the constructor
OverlayControlID = "ProAppModule1_EmbeddableControl1";
}
// Override the MapTool base class' OverlayControlPositionRatio property to set the position of the embeddable control
protected static void OnToolMouseDown(MapViewMouseButtonEventArgs e)
{
if (e.ChangedButton == MouseButton.Left)
e.Handled = true;
}
// Override the MapTool base class' HandleMouseDownAsync method to set the position of the embeddable control
protected static Task HandleMouseDownAsync(MapViewMouseButtonEventArgs e)
{
return QueuedTask.Run(() =>
{
Point
//assign the screen coordinate clicked point to the MapTool base class' OverlayControlLocation property.
OverlayControlPositionRatio = e.ClientPoint;
});
}C:\>"C:\Program Files\ArcGIS Pro\bin\ArcGISPro.exe"If your Add-in requires the use of custom command line arguments your arguments must be of the form "/argument" - note the forward slash "/". There must be no white space. If the command line contains a project to be opened (see Open project from command line) then custom arguments or switches must be placed before the project filename argument.
string[] args = System.Environment.GetCommandLineArgs();
foreach (var arg in args)
{
// look for your command line switches
}Application accelerators can be added to your Add-in config.daml using an accelerators/insertAccelerator DAML element with the refID of the element to which you are associating the accelerator (i.e. short cut).
<accelerators>
<insertAccelerator refID="esri_core_openProjectButton" flags="Ctrl" key="O" />
<insertAccelerator refID="esri_core_redoButton" flags="Ctrl" key="Y" />
<insertAccelerator refID="esri_core_undoButton" flags="Ctrl" key="Z" />
</accelerators>Note: Use the deleteAccelerator and updateAccelerator DAML elements within an updateModule element to remove or alter application accelerators respectively. Flags can be one of: Shift, Ctrl, Alt, Ctrl+Shift, Alt+Shift, Ctrl+Alt, Ctrl+Alt+Shift
There are many ArcGIS Pro styles defined which can be applied to buttons, labels and other controls on your panes and dockpanes to make your add-ins look and feel seamless with ArcGIS Pro. Some of the most common styles are listed below. For more styles and colors see the Styling-With-ArcGIS-Pro sample in the Community Samples repo.
Button styles
<Button Content="Button" Style="{StaticResource Esri_SimpleButton}" ToolTip="Button">
<Button Content="Button" Style="{StaticResource Esri_BackButton}" ToolTip="Button">
<Button Content="Button" Style="{StaticResource Esri_BackButtonSmall}" ToolTip="Button">
<Button Content="Button" Style="{StaticResource Esri_CloseButton}" ToolTip="Button">Dockpane heading style
<TextBlock Text="MyDockPane" Style="{StaticResource DockPaneHeading}"
VerticalAlignment="Center" HorizontalAlignment="Center"/>
Home | API Reference | Requirements | Download | Samples | Snippets
-
Determine if the application is busy
-
Get the Application main window
-
Set the current tool
-
Activate a tab
-
Activate/Deactivate a state - to modify a condition
-
Close ArcGIS Pro
-
Get ArcGIS Pro version
-
ProWindow Position on Screen
-
Get an Image Resource from the Current Assembly
-
Prevent ArcGIS Pro from Closing
-
Determine when a project is opened
-
Suggested command options in CommandSearch when a tab is activated.
-
Close a specific pane
-
Activate a pane
-
Find a dockpane
-
Dockpane operations
-
Dockpane undo / redo
-
Find a dockpane and obtain its ViewModel
-
Subscribe and unsubscribe to events when the dockpane is visible or hidden