-
Notifications
You must be signed in to change notification settings - Fork 117
ProGuide Command Filter
Language: C#
Subject: Framework
Contributor: ArcGIS Pro SDK Team <[email protected]>
Organization: Esri, http://www.esri.com
Date: 04/25/2025
ArcGIS Pro: 3.5
Visual Studio: 2022
This guide demonstrates how to implement a "Customization Filter", a.k.a. "Command Filter". "Customization Filters" give developers the opportunity to limit or filter ArcGIS Pro DAML command functionality. Before any command defined in DAML is executed, the registered CustomizationFilters are consulted and any DAML command can either be disabled on the UI or prevented from executing once clicked.
In this Topic
- Using Command Filter in your Add-in
- Disabling a DAML Command on the UI
- Filtering a DAML Command on Click
"Command Filters", a.k.a. "Customization Filters", give developers the opportunity to limit ArcGIS Pro DAML command functionality by stopping a command before its execution or by disabling a command in the UI. This is useful when you want to prevent a command from executing based on certain conditions, such as the current state of the application or the user's permissions or want to create some sort of auditing capability to record which commands have been clicked.
To implement a "Command Filter", create a class that is derived from the abstract ArcGIS Pro API class ArcGIS.Desktop.Framework.Contracts.CustomizationFilter
.
This new "Command Filter" can override two virtual methods: OnCanExecuteCommand
and OnExecuteCommand
. The OnCanExecuteCommand
method is called to define the Command's UI state: return 'true' to enable the Command's UI, return 'false' to disable the Command's UI. The OnExecuteCommand
method is called whenever a command is clicked on the UI. If the method returns true, the command is executed and if the method returns false the command is not executed.
To activate a Command Filter and start "filtering", call ArcGIS.Desktop.Framework.FrameworkApplication.RegisterCustomizationFilter(this)
. To deactivate a command filter to stop filtering, call ArcGIS.Desktop.Framework.FrameworkApplication.UnregisterCustomizationFilter(this)
. "this" refers to the instance reference of "your" command filter class.
Create an add-in project and name the project "CommandFilter".
In this example, we are going to be registering our command filter automatically at start-up. Otherwise, some other action would be needed within your addin to register the command filter (eg a button, check box, menu option, etc.) or in response to an event or a dockpane being opened and so forth. In the Config.daml, set your autoLoad attribute, on the <insertModule ...
tag, to "true". This ensures that your addin module will be loaded when ArcGIS Pro starts.
Change the module caption attribute to "Command Filter".
<modules>
<insertModule id="CommandFilter_Module" className="Module1" autoLoad="true" caption="Command Filter">
...
</insertModule>
</modules>
Add a new class file to the project called "CommandFilter.cs". Derive your custom "CommandFilter" class from the ArcGIS.Desktop.Framework.Contracts.CommandFilter
base class. Add a custom public Register and UnRegister method to your class. Call FrameworkApplication.RegisterCustomizationFilter(this)
and FrameworkApplication.RegisterCustomizationFilter(this)
respectively to register and unregister your command filter. Your implementation should look like this:
using ArcGIS.Desktop.Framework;
using ArcGIS.Desktop.Framework.Contracts;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CommandFilterExample
{
internal class CommandFilter : CustomizationFilter
{
/// <summary>
/// Register for command filtering. Customization filters must be registered before they are
/// called.
/// </summary>
public void Register()
{
FrameworkApplication.RegisterCustomizationFilter(this);
}
/// <summary>
/// Unregister for command filtering
/// </summary>
public void UnRegister()
{
FrameworkApplication.UnregisterCustomizationFilter(this);
}
}
}
Add code within your Module to automatically register your command filter at startup. The Module class provides an Initialize
method for this purpose. We will use this method to register our CommandFilter. Add the following code to the Module1 class:
#region Overrides for CommandFilter registration
private CommandFilter _commandFilter = null;
protected override bool Initialize()
{
// register the command filter
_commandFilter = new CommandFilter();
_commandFilter.Register();
return base.Initialize();
}
//...if you want to unregister your filter, call "UnRegister()"...
//protected override void Uninitialize()
//{
// // unregister the command filter
// if (_commandFilter != null)
// {
// _commandFilter.UnRegister();
// _commandFilter = null;
// }
// base.Uninitialize();
//}
#endregion Overrides for CommandFilter registration
At this juncture, compile and run your add-in to verify that there are no build errors.
The command filter class can change any DAML command's UI 'enabled' state based on whatever is the desired business logic or workflow. CommandFilters override OnExecuteCommand(string cmdID, string moduleID)
for this purpose. OnCanExecuteCommand(...)
is polled by the application on every UI refresh cycle. Return either true or false to enable or disable whichever are the desired command/commands. The daml id of the command being refreshed will be passed in as the first argument to the OnCanExecuteCommand method. Given that OnCanExecuteCommand is called so frequently, logic to determine whether a given command should be enabled or disabled should be extremely light. Querying external databases or performing complex logic will cause the performance of application refresh to suffer.
In this example we will hard-code disabling of the "Modify Features" button on the UI. To do this, we override the OnCanExecuteCommand
method in the CommandFilter class and return 'false' whenever the esri_editing_ShowEditFeaturesBtn
UI is refreshed.
Add the following code to the CommandFilter class:
/// <summary>
/// Gives a customization filter the ability to disable commands.
/// </summary>
/// <param name="cmdID">The DAML ID of the command about to execute.</param>
/// <param name="moduleID">The command's parent module DAML ID.</param>
/// <returns>false to disable the command; true to enable the command</returns>
protected override bool OnCanExecuteCommand(string cmdID, string moduleID)
{
if (cmdID == "esri_editing_ShowEditFeaturesBtn")
{
return false;
}
return true;
}
Back in the CommandFilter class, we are ready to implement the Filter Command logic by overriding OnExecuteCommand. This method is called before any DAML defined command is executed. If the method returns true, the command is executed; if the method returns false, the command is not executed. Same as with the OnCanExecuteCommand method, logic should be lightweight so as not to impair the performance of application commands. In this example we will hard-code disabling the command execution of the "Show Create Features" button whenever it is clicked.
Add the following code to the CommandFilter class:
/// <summary>
/// Implement your custom filtering logic here. OnCommandExecute is called every time
/// a command is clicked on the UI.
/// </summary>
/// <param name="ID">DAML ID of the command that is executing</param>
/// <returns>true to filter the command; false to execute the command</returns>
protected override bool OnExecuteCommand(string ID)
{
if (ID == "esri_editing_ShowCreateFeaturesBtn")
{
MessageBox.Show("Create Features button is disabled");
return false;
}
return true;
}
Compile and run the add-in. Test the logic by clicking on the "Create Features" button. You should see a message box indicating that the button is disabled. On the UI, the "Modify Features" button should be disabled.
For a more elaborate example, consider the following community sample: https://github.com/Esri/arcgis-pro-sdk-community-samples/tree/master/Framework/CommandCustomizationFilter
Home | API Reference | Requirements | Download | Samples
- Overview of the ArcGIS Pro SDK
- What's New for Developers at 3.5
- Installing ArcGIS Pro SDK for .NET
- Release notes
- Resources
- Pro SDK Videos
- ProSnippets
- ArcGIS Pro API
- ProGuide: ArcGIS Pro Extensions NuGet
Migration
- ProConcepts: Framework
- ProConcepts: Asynchronous Programming in ArcGIS Pro
- ProConcepts: Advanced topics
- ProGuide: How to Increment Addin Version Number
- ProGuide: Custom settings
- ProGuide: Command line switches for ArcGISPro.exe
- ProGuide: Reusing ArcGIS Pro Commands
- ProGuide: Licensing
- ProGuide: Digital signatures
- ProGuide: Command Search
- ProGuide: Keyboard shortcuts
- ProSnippets: Framework
- ProSnippets: DAML
Add-ins
- ProConcepts: Localization
- ProGuide: Installation and Upgrade
- ProGuide: Your first add-in
- ProGuide: ArcGIS AllSource Project Template
- ProGuide: Content and Image Resources
- ProGuide: Embedding Toolboxes
- ProGuide: Diagnosing ArcGIS Pro Add-ins
- ProGuide: Regression Testing
Configurations
Customization
- ProGuide: The Ribbon, Tabs and Groups
- ProGuide: Buttons
- ProGuide: Label Controls
- ProGuide: Checkboxes
- ProGuide: Edit Boxes
- ProGuide: Combo Boxes
- ProGuide: Context Menus
- ProGuide: Palettes and Split Buttons
- ProGuide: Galleries
- ProGuide: Dockpanes
- ProGuide: Code Your Own States and Conditions
- ProGuide: Command Filter
Styling
- ProConcepts: Project Content and Items
- ProConcepts: Custom Items
- ProGuide: Custom Items
- ProGuide: Custom browse dialog filters
- ProSnippets: Content
- ProSnippets: Browse Dialog Filters
- ArcGIS Pro TypeID Reference
- ProConcepts: Editing
- ProConcepts: COGO
- ProConcepts: Annotation Editing
- ProConcepts: Dimension Editing
- ProGuide: Editing Tool
- ProGuide: Sketch Tool With Halo
- ProGuide: Construction Tools with Options
- ProGuide: Annotation Construction Tools
- ProGuide: Annotation Editing Tools
- ProGuide: Knowledge Graph Construction Tools
- ProGuide: Templates
- ProSnippets: Editing
3D Analyst Data
Plugin Datasources
Topology
Linear Referencing
Object Model Diagram
- ProConcepts: Geometry
- ProConcepts: Multipatches
- ProGuide: Building Multipatches
- ProSnippets: Geometry
- ProSnippets: Geometry Engine
Relational Operations
- ProConcepts: Knowledge Graph
- ProGuide: Knowledge Graph Construction Tools
- ProSnippets: Knowledge Graph
Reports
Presentations
- ProConcepts: Map Authoring
- ProConcepts: Annotation
- ProConcepts: Dimensions
- ProGuide: Tray buttons
- ProGuide: Custom Dictionary Style
- ProGuide: Geocoding
- ProSnippets: Map Authoring
- ProSnippets: Annotation
- ProSnippets: Charts
- ProSnippets: Labeling
- ProSnippets: Renderers
- ProSnippets: Symbology
- ProSnippets: Text Symbols
3D Analyst
CIM
Graphics
Scene
Stream
Voxel
- ProConcepts: Map Exploration
- ProGuide: Map Pane Impersonation
- ProGuide: TableControl
- ProSnippets: Map Exploration
- ProSnippets: Custom Pane with Contents
Map Tools
- ProGuide: Feature Selection
- ProGuide: Identify
- ProGuide: MapView Interaction
- ProGuide: Embeddable Controls
- ProGuide: Custom Pop-ups
- ProGuide: Dynamic Pop-up Menu
Network Diagrams
- ProConcepts: Workflow Manager
- ProSnippets: Workflow Manager
- ProConcepts: Workflow Manager Classic (deprecated)
- ArcGIS Pro API Reference Guide
- ArcGIS Pro SDK (pro.arcgis.com)
- arcgis-pro-sdk-community-samples
- ArcGISPro Registry Keys
- ArcGIS Pro DAML ID Reference
- ArcGIS Pro Icon Reference
- ArcGIS Pro TypeID Reference
- ProConcepts: Distributing Add-Ins Online
- ProConcepts: Migrating to ArcGIS Pro
- FAQ
- Archived ArcGIS Pro API Reference Guides
- Dev Summit Tech Sessions