Skip to content

ProGuide Command Filter

UmaHarano edited this page May 12, 2025 · 1 revision
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.

CommandFilter

In this Topic

Command Filter

"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.

Implementation Summary

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.

Step 1:

Create an add-in project and name the project "CommandFilter".

Step 2:

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>

Step 3:

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);
      }
   }
}

Step 4

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.

Step 5

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;
}

Step 6

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

Developing with ArcGIS Pro

    Migration


Framework

    Add-ins

    Configurations

    Customization

    Styling


Arcade


Content


CoreHost


DataReviewer


Editing


Geodatabase

    3D Analyst Data

    Plugin Datasources

    Topology

    Linear Referencing

    Object Model Diagram


Geometry

    Relational Operations


Geoprocessing


Knowledge Graph


Layout

    Reports

    Presentations


Map Authoring

    3D Analyst

    CIM

    Graphics

    Scene

    Stream

    Voxel


Map Exploration

    Map Tools


Networks

    Network Diagrams


Parcel Fabric


Raster


Sharing


Tasks


Workflow Manager


Reference

Clone this wiki locally