ProGuide Buttons - EsriJapan/arcgis-pro-sdk GitHub Wiki

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

ProGuide では、ボタンを宣言する方法を段階的に説明しています。ただし、あくまでも参考情報のため、ボタン アイテム テンプレートを使用する方法を推奨しています。

トピック

ボタンの宣言方法

ボタンはすべてのコントロールの中で最もシンプルで、controls コンテナ内の button 要素を使用して DAML で宣言します。

ボタンは、idcaptionclassNametooltip 属性を使用して宣言します。ボタンに画像を関連付ける場合は、largeImagesmallImage 属性を指定します。

ボタンは、button コントロールの refID 属性を使用して group で参照します。

<groups>
   <group id="MyGroup" caption="Group 1">
      <button refID="ProAppModule_Button1" size="large" />
   </group>
</groups>
<controls>
   <button id="ProAppModule_Button1" caption="Button 1" className="MyCustomButton" 
  largeImage="GenericButtonBlue32" smallImage="GenericButtonBlue16">
      <tooltip heading="Tooltip Heading">Show a message box with the project URI<disabledText />
      </tooltip>
   </button>
</controls>

ボタンの実装は、className 属性で指定します。上記の MyCustomButton クラスは、ArcGIS.Desktop.Framework.Contracts.Button 基底クラスを継承します。仮想メソッド OnClickOnUpdate をオーバーライドして、必要なカスタム動作を実行します。

internal class MyCustomButton : ArcGIS.Desktop.Framework.Contracts.Button
{
   protected override void OnClick()
   {
      string uri = ArcGIS.Desktop.Core.Project.Current.URI;
      ArcGIS.Desktop.Framework.Dialogs.MessageBox.Show($"Project uri {uri}"); 
   }

   protected override void OnUpdate()
   {
      // TODO - add specific code here to control enabled state
   }
}

condition を使用してボタンの有効状態を制御

ほとんどの場合、ボタンの有効状態は、アプリケーション内の特定の condition (条件) に依存します。例えば、[データの追加] ボタンは、マップ ペインが開いている時にのみ有効になります。定義済みの条件を割り当てるには、condition 属性を使用します。DAML での state (状態) と condition (条件) の定義の詳細については、そのセクションを参照してください。

<button id="ProAppModule_Button1" caption="Button 1" className="Button1"
  largeImage="GenericButtonBlue32" smallImage="GenericButtonBlue16" condition="esri_mapping_mapPane">
   <tooltip heading="Tooltip Heading">Show a message box with the project URI<disabledText />
   </tooltip>
</button>

ボタンの無効時にツールチップにカスタム テキストを表示

ボタンの有効状態を制御するだけでなく、ツールチップにカスタム メッセージを追加して、ボタンが無効になっている理由を説明することもできます。これは、ボタンのツール チップの disabledText 属性を使用して行います。

<controls>
  <!-- add your controls here -->
   <button id="ProAppModule_Button1" caption="Button 1" className="Button1" loadOnClick="true" 
        smallImage="GenericButtonBlue16" largeImage="GenericButtonBlue32">
          <tooltip heading="Tooltip Heading">Show a message box with the project URI
          <disabledText>Text that is shown when the button is disabled</disabledText></tooltip>
   </button>
</controls>

Disabled tooltip

ボタンの拡張キャプションを設定

フォーマットなど、多くのキャプションはあいまいで何度も複製されます。 これを解決するには、コントロールの extendedCaption 属性を使用して、より詳細な情報を提供します。名前の衝突がなく、通常のキャプションに基づいてコントロールの意味が明確な場合は、拡張キャプションを提供する必要はありません。 extendedCaption 属性は、[カスタマイズ] や [タスク] ダイアログ ボックスでキャプションと一緒に括弧で囲まれて表示されます。

ボタンにキー チップを追加

リボン コントロールでは、キー チップを使ってリボンのタブ、グループ、アイテムにキーボードでアクセスすることができます。keyTip 属性を使用して、カスタム ボタン (およびタブ) にキー チップを追加します。各コントロールに設定したキー チップは、表示されているタブ上のすべてのコントロール間で一意であることを確認する必要があります。

<controls>
  <!-- add your controls here -->
   <button id="ProAppModule_Button1" caption="Button 1" className="Button1" loadOnClick="true" 
        smallImage="GenericButtonBlue16" largeImage="GenericButtonBlue32"
        keyTip="CB">
          <tooltip heading="Tooltip Heading">Show a message box with the project URI
          <disabledText>Text that is shown when the button is disabled</disabledText></tooltip>
   </button>
</controls>

ALT キーを使用すると、様々なタブやボタンに関連するキー チップを確認できます。

アプリケーションのキー チップ (ALT を使用) keytips

アドインタブのキー チップ (ALT + Z を使用)
keytips_ViewTab

ボタンにメニュー キー チップを追加

menuKeytip 属性は、コンテキストメニューやリボンメニューに表示されるボタンをシングルキーで実行できるようにするために、下線付きのアクセスキーを割り当てるために使われます。

image

アンダーライン アクセス キーを確実に表示するには、ArcGIS Pro の [オプション] ダイアログ ボックスの [アプリケーション] メニューで [ユーザー インタフェイス] をクリックし、[ショートカット メニューにキーボード ショートカットが存在する場合は表示] チェック ボックスをオンにします。

menuKeytip 属性の有効な値は 1 文字に制限されています。複数のメニュー項目が同じショートカット文字を使用することは許容されます; このような場合、メニューを呼び出す代わりに、メニューは重複する項目を循環し、ENTERキーは選択項目を呼び出すために使用されます。メニューのショートカットを実装するためにkeytip 属性を使用している古いコードベースの人は、keytip がメニューと互換性がない場合のために追加されたので、menuKeytip 属性へのアップデートを検討する必要があります。

ボタンがリボンとメニューの両方に表示される場合、keytip 属性と menuKeytip 属性を一緒に使うことができます。このシナリオでは、ボタン要素に両方の属性を定義することができ、ボタンがリボン表面に表示されるときには、keytip 定義が使用され、メニュー内に表示されるときには、menuKeytip が使用されてアクセスキーが割り当てられます。

<controls>
  <!-- add your controls here -->
   <button id="ContextMenuShortcut_Button" caption="Custom Button" className="Button1" loadOnClick="true" menuKeytip="M" 
           smallImage="GenericButtonBlue16" largeImage="GenericButtonBlue32" />
</controls>

ボタンのプリロード

loadOnClick 属性は、フレームワークがボタンを作成するタイミングを決定します。デフォルトでは、コントロールは有効になっているように見えますが、クリックされるまで実際にはインスタンス化されません。この Just-In-Time 方式は、コントロールのインスタンス化をエンド ユーザーによって開始されるまで延期することにより、リソースの使用率と起動時間を改善します。loadOnClick 属性のデフォルト値は true です。ボタンをプリロードするには、この属性を false に変更します。

コマンドのデリゲート

モジュールは、リボン内のボタンの作成を簡素化するためのパターンである DelegateCommands をサポートしています。抽象ボタン クラスを継承する完全なボタン プラグイン クラスを作成する代わりに、ボタンが実際にはモジュール クラスの単なる static メソッドであることを宣言できます。

以下のサンプルでは、OnCustomButtonClick という名前の静的メソッド (Module1 クラス上) を使用して DelegateCommand を実装しています。DAML では、ボタン要素の className 属性は、Module クラスの ID と、呼び出す静的メソッドの名前をコロン ":" で区切って保持します。

<insertModule id="MyAddIn_Module" className="Module1" autoLoad="false" caption="Module1">
   <tabs>...</tabs>
   <groups>...</groups>
   <controls>
      <button id="MyAddIn_Module_Button" className="MyAddIn_Module:OnCustomButtonClick" caption="Button1"             largeImage="GenericButtonBlack32" smallImage="GenericButtonBlack16">
    <tooltip>Tooltip text</tooltip>
</button>
   </controls>
</insertModule> 

Module1.cs では、静的メソッド OnCustomButtonClick が OnClick ハンドラーを実装しています。

internal class Module1 : Module {
   //Delegate command OnClick handler
   internal static void OnCustomButtonClick() {
        System.Diagnostics.Debug.WriteLine("Button clicked");
   }

DelegateCommand の "response" メソッドは、通常、private または internal である必要があることに注意してください。

DelegateCommands は、bool を返す静的プロパティを介して OnUpdate 関数を追加でサポートできます。プロパティは、接頭辞 Can が付いた DelegateCommand の OnClick メソッドと同じ名前である必要があります。

この例では、OnClick メソッドは OnCustomButtonClick と呼ばれるため、プロパティは Can OnCustomButtonClick と呼ばれる必要があります。

internal class Module1 : Module {
   private static bool _isEnabled = true;

   //Delegate command OnClick handler
   internal static void OnCustomButtonClick() {
        System.Diagnostics.Debug.WriteLine("Button clicked");
   }

   //Delegate command OnUpdate implementation
   internal static bool CanOnCustomButtonClick {
      get {
          //Module1 code must keep '_isEnabled' current
          return _isEnabled;
      }
   }

この DelegateCommand パターンは、リボンに表示されるボタンにのみ適していることに注意してください。デリゲート コマンドは、ProConcepts フレームワーク にも記載されています。

ボタンのキャプションを変更

更新操作は、接頭辞 update を使用して実行できます。以下の例では、以前に挿入されたボタンのキャプションを、updateButton 要素を使用して更新しています。既存のオブジェクトを参照するために使用する refID 属性にも注意してください。更新は、ボタンが属する適切なモジュールを参照して、updateModule 要素内に存在する必要があります。

<updateModule refID="acme_MainModule">
   <controls>
      <updateButton refID="esri_SubSystem_Button1" caption="New Caption"/>
   </controls>
</updateModule>

ボタンの condition を変更

すべての属性を更新できるわけではありません。ボタンの condition を変更することはできません。condition は、DAML 宣言を介してのみ設定できます。

ボタンの削除

削除操作は、接頭辞 delete を使用して実行できます。以下の例では、以前に挿入されたボタンを、deleteButton 要素を使用して UI から削除しています。 既存のオブジェクトを参照するために使用される refID 属性にも注意してください。

<updateModule refID="acme_MainModule">
   <controls>
      <deleteButton refID="esri_SubSystem_Button1"/>
   </controls>
</updateModule>

別のモジュールが所有するグループにボタンを配置

updateGroup 要素と insertButton 要素を使用して、別のモジュールが所有するグループにボタンを追加します。これは更新操作のため、DAML にはグループが属する適切なモジュールを参照する updateModule 要素が必要です。placeWithinsert 属性を使用すると、グループ内の別のアイテムを基準にしてアイテムを配置できます。insert 属性は、"before" または "after" の値を持つことができます。

<modules>
   <updateModule refID="esri_mapping">
      <groups>
         <updateGroup refID="esri_mapping_selectionGroup">
            <insertButton refID="esri_editing_ShowAttributes" size="middle"
                                placeWith="esri_mapping_clearSelectionButton" insert="before" />
         </updateGroup>      
      </groups>    
   </updateModule>    
</modules>

プログラム実行時にボタンにアクセス

FrameworkApplication.GetPlugInWrapper 関数とコントロール識別子を使用して、実行時にすべてのコントロールにアクセスして更新できます。

protected override void OnClick()
{
   IPlugInWrapper wrapper = FrameworkApplication.GetPlugInWrapper("acme_ZoomBtn");
   wrapper.Caption = "New Caption";
   wrapper.Tooltip = "New Tooltip";
}

プログラム実行時にボタンの画像を変更

ボタン画像は、基底クラス ArcGIS.Desktop.Framework.Contracts.Plugin から継承された SmallImage および LargeImage プロパティを介して実行時に変更可能です。画像プロパティのいずれかに異なる画像ソースを割り当てることで、画像を置き換えることができます。この例では、ボタンの大画像が、連続するボタンクリックごとに Pro SDK の BexDog32MarsCat32 画像の間で切り替わっています。

internal class Button3 : Button
{
   static int count = 0;
   protected override void OnClick()
   {
     if (count % 2 == 0)
       this.LargeImage = new BitmapImage(
          new Uri(
            @"pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/BexDog32.png"));
     else
      this.LargeImage = new BitmapImage(
          new Uri(
            @"pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/MarsCat32.png"));
     count++;
     ...

プログラム実行時にボタンを実行

protected override void OnClick()
{
   IPlugInWrapper wrapper = FrameworkApplication.GetPlugInWrapper("esri_mapping_zoomToSelectionButton");
   var command = wrapper as ICommand; // tool and command(Button) supports this

   if ((command != null) && command.CanExecute(null))
      command.Execute(null);
}

チェック ボタンの作成

DAML でボタンを通常通りに定義します。ボタン クラスの OnClick イベントをオーバーライドして、IsChecked ランタイム プロパティを変更してチェック状態を設定します。

<button id="AppCustomization_CheckedButton" caption="Lock" className="MyCheckedButton" loadOnClick="false" >
   <tooltip heading="Checked button"></tooltip>
</button>
internal class MyCheckedButton : Button
{
   public MyCheckedButton()
   {
      IsChecked = false;
      Caption = "Lock";
      SmallImage = new System.Windows.Media.Imaging.BitmapImage(new Uri(
 @"pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericUnLockNoColor16.png"));
      LargeImage = new System.Windows.Media.Imaging.BitmapImage(new Uri(
 @"pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericUnLockNoColor32.png"));
   }

   protected override void OnClick()
   {
      IsChecked = !IsChecked;

      if (IsChecked)
      {
         //Toggle the small and large button images on the ribbon to reflect
         //the changed state of the button
         Caption = "Unlock";
         SmallImage = new System.Windows.Media.Imaging.BitmapImage(new Uri(
 "pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericLockNoColor16.png"));
         LargeImage = new System.Windows.Media.Imaging.BitmapImage(new Uri(
 "pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericLockNoColor32.png"));
      }
      else
      {
         Caption = "Lock";
         SmallImage = new System.Windows.Media.Imaging.BitmapImage(new Uri(
@"pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericUnLockNoColor16.png"));
         LargeImage = new System.Windows.Media.Imaging.BitmapImage(new Uri(
@"pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericUnLockNoColor32.png"));
      }
   }      
}
⚠️ **GitHub.com Fallback** ⚠️