ArcGIS Pro SDK (三)Addin控件 1 按钮类

ArcGIS Pro SDK (一)Addin控件

目录

  • ArcGIS Pro SDK (一)Addin控件
    • 1 Addin控件
    • 2 ArcGIS Pro 按钮
      • 2.1 添加控件
      • 2.2 Code
    • 3 ArcGIS Pro 按钮面板
      • 3.1 添加控件
      • 3.2 Code
    • 4 ArcGIS Pro 菜单
      • 4.1 添加控件
      • 4.2 Code
    • 5 ArcGIS Pro 分割按钮
      • 5.1 添加控件
      • 5.2 Code
    • 6 ArcGIS Pro 图库
      • 6.1 添加控件
      • 6.2 Code
    • 7 ArcGIS Pro 内嵌图库
      • 7.1 添加控件
      • 7.2 Code
    • 8 ArcGIS Pro 组合框
      • 8.1 添加控件
      • 8.2 Code
    • 9 ArcGIS Pro 自定义控件
      • 9.1 添加控件
      • 9.2 Code
    • 10 ArcGIS Pro 地图工具
      • 10.1 添加控件
      • 10.2 Code
    • 11 ArcGIS Pro 嵌入式控件
      • 11.1 添加控件
      • 11.2 Code
    • 12 ArcGIS Pro 布局工具
      • 12.1 添加控件
      • 12.2 Code
    • 13 ArcGIS Pro 地图托盘按钮
      • 13.1 添加控件
      • 13.2 Code
    • 14 ArcGIS Pro 布局托盘按钮
      • 14.1 添加控件
      • 14.2 Code

1 Addin控件

在ArcGIS Pro中,Add-In控件(Add-In Controls)是用于扩展和定制ArcGIS Pro用户界面的组件。这些控件允许开发者添加自定义功能和工具,以满足特定的工作需求。

image-20240604111059193

image-20240604111143863

2 ArcGIS Pro 按钮

2.1 添加控件

image-20240604111349812

image-20240604112003042

image-20240604112316343

2.2 Code

ButtonTest.cs

using ArcGIS.Desktop.Framework.Contracts;
using ArcGIS.Desktop.Framework.Dialogs;

namespace WineMonk.Demo.ProAppModule.Code01_MenuButton
{
    internal class ButtonTest : Button
    {
        protected override void OnClick()
        {
            // 点击事件...
            MessageBox.Show($"点击了按钮 - ID:{this.ID} Caption:{this.Caption}");
        }
    }
}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <button refID="WineMonk_Demo_ProAppModule_Code01_MenuButton_ButtonTest" size="large" />
                <buttonPalette refID="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest" />
                <menu refID="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest" size="middle" />
                <splitButton refID="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest" />
                <gallery refID="WineMonk_Demo_ProAppModule_Code05_Gallery_GalleryTest" inline="false" size="large" />
                <gallery refID="WineMonk_Demo_ProAppModule_Code06_InlineGallery_InlineGalleryTest" inline="true" size="large" />
                <comboBox refID="WineMonk_Demo_ProAppModule_Code07_ComboBox_ComboBoxTest" />
                <customControl refID="WineMonk_Demo_ProAppModule_Code08_CustomControl_CustomControlTest" size="large" />
                <tool refID="WineMonk_Demo_ProAppModule_Code09_MapTool_MapToolTest" size="large" />
                <tool refID="WineMonk_Demo_ProAppModule_Code10_EmbeddableControl_MapTools_OpenControlMapTool" size="large" />
            </group>
        </groups>
        <controls>
            <!-- add your controls here -->
            <!-- 在这里添加控件 -->
            <button id="WineMonk_Demo_ProAppModule_Code01_MenuButton_ButtonTest" caption="ButtonTest" className="WineMonk.Demo.ProAppModule.Code01_MenuButton.ButtonTest" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlue16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlue32.png">
                <tooltip heading="Tooltip Heading">
                    Tooltip text<disabledText /></tooltip>
            </button>
        </controls>
    </insertModule>
</modules>

3 ArcGIS Pro 按钮面板

3.1 添加控件

image-20240604113444904

image-20240604113612213

image-20240604114106229

3.2 Code

ButtonPaletteTest.cs

using ArcGIS.Desktop.Framework.Contracts;


namespace WineMonk.Demo.ProAppModule.Code02_ButtonPalette
{
    internal class ButtonPaletteTest_button1 : Button
    {
        protected override void OnClick()
        {
        }
    }

    internal class ButtonPaletteTest_button2 : Button
    {
        protected override void OnClick()
        {
        }
    }

    internal class ButtonPaletteTest_button3 : Button
    {
        protected override void OnClick()
        {
        }
    }

}

Config,daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <buttonPalette refID="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest" />
            </group>
        </groups>
        <controls>
            <!-- add your controls here -->
            <!-- 在这里添加控件 -->
            <button id="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest_Items_Button1" caption="Palette Button 1" className="WineMonk.Demo.ProAppModule.Code02_ButtonPalette.ButtonPaletteTest_button1" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGrey16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGrey32.png">
                <tooltip heading="Palette Button 1">
                    ToolTip<disabledText />
                </tooltip>
            </button>
            <button id="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest_Items_Button2" caption="Palette Button 2" className="WineMonk.Demo.ProAppModule.Code02_ButtonPalette.ButtonPaletteTest_button2" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGrey16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGrey32.png">
                <tooltip heading="Palette Button 2">
                    ToolTip<disabledText />
                </tooltip>
            </button>
            <button id="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest_Items_Button3" caption="Palette Button 3" className="WineMonk.Demo.ProAppModule.Code02_ButtonPalette.ButtonPaletteTest_button3" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGrey16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGrey32.png">
                <tooltip heading="Palette Button 3">
                    ToolTip<disabledText />
                </tooltip>
            </button>
        </controls>
        <palettes>
            <buttonPalette id="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest" caption="ButtonPaletteTest" dropDown="false" menuStyle="true">
                <button refID="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest_Items_Button1" />
                <button refID="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest_Items_Button2" />
                <button refID="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest_Items_Button3" />
            </buttonPalette>
        </palettes>
    </insertModule>
</modules>

4 ArcGIS Pro 菜单

4.1 添加控件

image-20240604114239218

image-20240604114357802

image-20240604114452027

4.2 Code

MenuTest.cs

using ArcGIS.Desktop.Framework.Contracts;

namespace WineMonk.Demo.ProAppModule.Code03_Menu
{
    internal class MenuTest_button1 : Button
    {
        protected override void OnClick()
        {
        }
    }

    internal class MenuTest_button2 : Button
    {
        protected override void OnClick()
        {
        }
    }

    internal class MenuTest_button3 : Button
    {
        protected override void OnClick()
        {
        }
    }

}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <menu refID="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest" size="middle" />
            </group>
        </groups>
        <controls>
            <!-- add your controls here -->
            <!-- 在这里添加控件 -->
            <button id="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest_Items_Button1" caption="Menu Button 1" className="WineMonk.Demo.ProAppModule.Code03_Menu.MenuTest_button1" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGreen16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGreen32.png">
                <tooltip heading="Menu Button 1">ToolTip<disabledText /></tooltip>
            </button>
            <button id="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest_Items_Button2" caption="Menu Button 2" className="WineMonk.Demo.ProAppModule.Code03_Menu.MenuTest_button2" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGreen16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGreen32.png">
                <tooltip heading="Menu Button 2">ToolTip<disabledText /></tooltip>
            </button>
            <button id="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest_Items_Button3" caption="Menu Button 3" className="WineMonk.Demo.ProAppModule.Code03_Menu.MenuTest_button3" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGreen16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGreen32.png">
                <tooltip heading="Menu Button 3">ToolTip<disabledText /></tooltip>
            </button>
        </controls>
        <menus>
            <menu id="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest" caption="MenuTest" smallImage="GenericButtonGreen16.png" largeImage="GenericButtonGreen32.png">
                <button refID="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest_Items_Button1" />
                <button refID="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest_Items_Button2" />
                <button refID="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest_Items_Button3" />
            </menu>
        </menus>
    </insertModule>
</modules>

5 ArcGIS Pro 分割按钮

5.1 添加控件

image-20240604114826959

image-20240604114856275

image-20240604114946859

5.2 Code

SplitButtonTest.cs

using ArcGIS.Desktop.Framework.Contracts;

namespace WineMonk.Demo.ProAppModule.Code04_SplitButton
{
    internal class SplitButtonTest_button1 : Button
    {
        protected override void OnClick()
        {
        }
    }

    internal class SplitButtonTest_button2 : Button
    {
        protected override void OnClick()
        {
        }
    }

    internal class SplitButtonTest_button3 : Button
    {
        protected override void OnClick()
        {
        }
    }

}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <splitButton refID="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest" />
            </group>
        </groups>
        <controls>
            <!-- add your controls here -->
            <!-- 在这里添加控件 -->
            <button id="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest_Items_Button1" caption="SplitButtonTest 1" className="WineMonk.Demo.ProAppModule.Code04_SplitButton.SplitButtonTest_button1" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlack16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlack32.png">
                <tooltip heading="Split Button 1">ToolTip<disabledText /></tooltip>
            </button>
            <button id="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest_Items_Button2" caption="SplitButtonTest 2" className="WineMonk.Demo.ProAppModule.Code04_SplitButton.SplitButtonTest_button2" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlack16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlack32.png">
                <tooltip heading="Split Button 2">ToolTip<disabledText /></tooltip>
            </button>
            <button id="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest_Items_Button3" caption="SplitButtonTest 3" className="WineMonk.Demo.ProAppModule.Code04_SplitButton.SplitButtonTest_button3" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlack16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonBlack32.png">
                <tooltip heading="Split Button 3">ToolTip<disabledText /></tooltip>
            </button>
        </controls>
        <splitButtons>
            <splitButton id="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest">
                <button refID="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest_Items_Button1" />
                <button refID="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest_Items_Button2" />
                <button refID="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest_Items_Button3" />
            </splitButton>
        </splitButtons>
    </insertModule>
</modules>

6 ArcGIS Pro 图库

6.1 添加控件

image-20240604115246712

image-20240604115328845

image-20240604115434338

6.2 Code

GalleryTest.cs

using ArcGIS.Desktop.Framework.Contracts;
using System.Windows.Media;

namespace WineMonk.Demo.ProAppModule.Code05_Gallery
{
    internal class GalleryTest : Gallery
    {
        private bool _isInitialized;

        protected override void OnDropDownOpened()
        {
            Initialize();
        }

        private void Initialize()
        {
            if (_isInitialized)
                return;

            //Add 6 items to the gallery
            for (int i = 0; i < 6; i++)
            {
                string name = string.Format("Item {0}", i);
                Add(new GalleryItem(name, this.LargeImage != null ? ((ImageSource)this.LargeImage).Clone() : null, name));
            }
            _isInitialized = true;

        }

        protected override void OnClick(GalleryItem item)
        {
            //TODO - insert your code to manipulate the clicked gallery item here
            System.Diagnostics.Debug.WriteLine("Remove this line after adding your custom behavior.");
            base.OnClick(item);
        }
    }
}

GalleryTestTemplate.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:ribbon="http://schemas.actiprosoftware.com/winfx/xaml/ribbon"
                    xmlns:extensions="clr-namespace:ArcGIS.Desktop.Extensions;assembly=ArcGIS.Desktop.Extensions">
    <ResourceDictionary.MergedDictionaries>
        <extensions:DesignOnlyResourceDictionary Source="pack://application:,,,/ArcGIS.Desktop.Framework;component\Themes\Default.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <DataTemplate x:Key="GalleryTestItemTemplate">
        <StackPanel Orientation="Vertical" Margin="5,0,5,0">
            <Grid Margin="5">
                <!-- The image for the gallery item-->
                <Image MaxHeight="32" MaxWidth="32">
                    <Image.Effect>
                        <DropShadowEffect Color="{DynamicResource Esri_Color_Gray145}" Opacity="0.4" />
                    </Image.Effect>
                    <Image.Style>
                        <Style TargetType="{x:Type Image}">
                            <Setter Property="Source" Value="{Binding Icon}"/>
                        </Style>
                    </Image.Style>
                </Image>
            </Grid>
            <TextBlock Text="{Binding Text}" HorizontalAlignment="Center" />
        </StackPanel>
    </DataTemplate> 
</ResourceDictionary>

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <gallery refID="WineMonk_Demo_ProAppModule_Code05_Gallery_GalleryTest" inline="false" size="large" />
            </group>
        </groups>
        <galleries>
            <gallery id="WineMonk_Demo_ProAppModule_Code05_Gallery_GalleryTest" caption="GalleryTest" className="WineMonk.Demo.ProAppModule.Code05_Gallery.GalleryTest" itemsInRow="3" dataTemplateFile="pack://application:,,,/WineMonk.Demo.ProAppModule;component/Code05_Gallery/GalleryTestTemplate.xaml" templateID="GalleryTestItemTemplate" resizable="true" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonOrange32.png">
                <tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
            </gallery>
        </galleries>
    </insertModule>
</modules>

7 ArcGIS Pro 内嵌图库

7.1 添加控件

image-20240604120020148

image-20240604133339782

image-20240604133503667

7.2 Code

InlineGalleryTest.cs

using ArcGIS.Desktop.Framework.Contracts;
using System.Windows.Media;

namespace WineMonk.Demo.ProAppModule.Code06_InlineGallery
{
    internal class InlineGalleryTest : Gallery
    {
        private bool _isInitialized;

        public InlineGalleryTest()
        {
            Initialize();
        }

        private void Initialize()
        {
            if (_isInitialized)
                return;
            _isInitialized = true;

            //Add 6 items to the gallery
            for (int i = 0; i < 6; i++)
            {
                string name = string.Format("Item {0}", i);
                Add(new GalleryItem(name, this.LargeImage != null ? ((ImageSource)this.LargeImage).Clone() : null, name));
            }

        }

        protected override void OnClick(GalleryItem item)
        {
            //TODO - insert your code to manipulate the clicked gallery item here
            System.Diagnostics.Debug.WriteLine("Remove this line after adding your custom behavior.");
            base.OnClick(item);
        }
    }
}

InlineGalleryTestTemplate.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:ribbon="http://schemas.actiprosoftware.com/winfx/xaml/ribbon"
                    xmlns:extensions="clr-namespace:ArcGIS.Desktop.Extensions;assembly=ArcGIS.Desktop.Extensions">
    <ResourceDictionary.MergedDictionaries>
        <extensions:DesignOnlyResourceDictionary Source="pack://application:,,,/ArcGIS.Desktop.Framework;component\Themes\Default.xaml"/>
    </ResourceDictionary.MergedDictionaries>
    <DataTemplate x:Key="InlineGalleryTestItemTemplate">
        <Grid Margin="0,0,0,0" Width="48" Height="66">
            <Grid.RowDefinitions>
                <RowDefinition Height="36"/>
                <RowDefinition Height="*"/>
            </Grid.RowDefinitions>
            <Image Grid.Row="0" Stretch="None" VerticalAlignment="Bottom" HorizontalAlignment="Center">
                <Image.Effect>
                    <DropShadowEffect Color="{DynamicResource Esri_Color_Gray145}" Opacity="0.4" />
                </Image.Effect>
                <Image.Style>
                    <Style TargetType="{x:Type Image}">
                        <Setter Property="Source" Value="{Binding Icon}"/>
                    </Style>
                </Image.Style>
            </Image>
            <TextBlock Grid.Row="1" MaxWidth="48" Text="{Binding Text}" HorizontalAlignment="Center" VerticalAlignment="Center" />
        </Grid>
    </DataTemplate>
</ResourceDictionary>

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <gallery refID="WineMonk_Demo_ProAppModule_Code06_InlineGallery_InlineGalleryTest" inline="true" size="large" />
            </group>
        </groups>
        <galleries>
            <gallery id="WineMonk_Demo_ProAppModule_Code06_InlineGallery_InlineGalleryTest" caption="InlineGalleryTest" className="WineMonk.Demo.ProAppModule.Code06_InlineGallery.InlineGalleryTest" itemsInRow="3" dataTemplateFile="pack://application:,,,/WineMonk.Demo.ProAppModule;component/Code06_InlineGallery/InlineGalleryTestTemplate.xaml" templateID="InlineGalleryTestItemTemplate" resizable="true" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonYellow32.png">
                <tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
            </gallery>
        </galleries>
    </insertModule>
</modules>

8 ArcGIS Pro 组合框

8.1 添加控件

image-20240604144531168

image-20240604144607172

image-20240604144659355

8.2 Code

ComboBoxTest.cs

using ArcGIS.Desktop.Framework.Contracts;
using System.Linq;

namespace WineMonk.Demo.ProAppModule.Code07_ComboBox
{
    /// <summary>
    /// Represents the ComboBox
    /// </summary>
    internal class ComboBoxTest : ComboBox
    {

        private bool _isInitialized;

        /// <summary>
        /// Combo Box constructor
        /// </summary>
        public ComboBoxTest()
        {
            UpdateCombo();
        }

        /// <summary>
        /// Updates the combo box with all the items.
        /// </summary>

        private void UpdateCombo()
        {
            // TODO – customize this method to populate the combobox with your desired items  
            if (_isInitialized)
                SelectedItem = ItemCollection.FirstOrDefault(); //set the default item in the comboBox


            if (!_isInitialized)
            {
                Clear();

                //Add 6 items to the combobox
                for (int i = 0; i < 6; i++)
                {
                    string name = string.Format("Item {0}", i);
                    Add(new ComboBoxItem(name));
                }
                _isInitialized = true;
            }


            Enabled = true; //enables the ComboBox
            SelectedItem = ItemCollection.FirstOrDefault(); //set the default item in the comboBox

        }

        /// <summary>
        /// The on comboBox selection change event. 
        /// </summary>
        /// <param name="item">The newly selected combo box item</param>
        protected override void OnSelectionChange(ComboBoxItem item)
        {

            if (item == null)
                return;

            if (string.IsNullOrEmpty(item.Text))
                return;

            // TODO  Code behavior when selection changes.    
        }

    }
}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <comboBox refID="WineMonk_Demo_ProAppModule_Code07_ComboBox_ComboBoxTest" />
            </group>
        </groups>
        <controls>
            <!-- add your controls here -->
            <!-- 在这里添加控件 -->
            <comboBox id="WineMonk_Demo_ProAppModule_Code07_ComboBox_ComboBoxTest" caption="ComboBoxTest" className="WineMonk.Demo.ProAppModule.Code07_ComboBox.ComboBoxTest" itemWidth="140" extendedCaption="Extended Caption" isEditable="false" isReadOnly="true" resizable="true">
                <tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
            </comboBox>
        </controls>
    </insertModule>
</modules>

9 ArcGIS Pro 自定义控件

9.1 添加控件

image-20240604145103179

image-20240604145214196

image-20240604145315558

9.2 Code

CustomControlTest.xaml

<UserControl x:Class="WineMonk.Demo.ProAppModule.Code08_CustomControl.CustomControlTestView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"   
             xmlns:ui="clr-namespace:WineMonk.Demo.ProAppModule.Code08_CustomControl"
             xmlns:extensions="clr-namespace:ArcGIS.Desktop.Extensions;assembly=ArcGIS.Desktop.Extensions"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             d:DataContext="{Binding Path=ui.CustomControlTestViewModel}">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <extensions:DesignOnlyResourceDictionary Source="pack://application:,,,/ArcGIS.Desktop.Framework;component\Themes\Default.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid Height="68">
        <TextBlock Text="{Binding Text}" HorizontalAlignment="Center" VerticalAlignment="Center" />
    </Grid>
</UserControl>

CustomControlTestViewModel.cs

using ArcGIS.Desktop.Framework.Contracts;



namespace WineMonk.Demo.ProAppModule.Code08_CustomControl
{
    internal class CustomControlTestViewModel : CustomControl
    {
        /// <summary>
        /// Text shown in the control.
        /// </summary>
        private string _text = "Custom Control";
        public string Text
        {
            get { return _text; }
            set
            {
                SetProperty(ref _text, value, () => Text);
            }
        }
    }
}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <customControl refID="WineMonk_Demo_ProAppModule_Code08_CustomControl_CustomControlTest" size="large" />
            </group>
        </groups>
        <controls>
            <!-- add your controls here -->
            <!-- 在这里添加控件 -->
            <customControl id="WineMonk_Demo_ProAppModule_Code08_CustomControl_CustomControlTest" caption="CustomControlTest" className="WineMonk.Demo.ProAppModule.Code08_CustomControl.CustomControlTestViewModel" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonPurple16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonPurple32.png">
                <content className="WineMonk.Demo.ProAppModule.Code08_CustomControl.CustomControlTestView" />
                <tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
            </customControl>
        </controls>
    </insertModule>
</modules>

10 ArcGIS Pro 地图工具

10.1 添加控件

image-20240604145919738

image-20240604145949927

image-20240604150139144

10.2 Code

MapTool.cs

using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Mapping;
using System.Threading.Tasks;

namespace WineMonk.Demo.ProAppModule.Code09_MapTool
{
    internal class MapToolTest : MapTool
    {
        public MapToolTest()
        {
            IsSketchTool = true;
            SketchType = SketchGeometryType.Rectangle;
            SketchOutputMode = SketchOutputMode.Map;
        }

        protected override Task OnToolActivateAsync(bool active)
        {
            return base.OnToolActivateAsync(active);
        }

        protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
        {
            return base.OnSketchCompleteAsync(geometry);
        }
    }
}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <tool refID="WineMonk_Demo_ProAppModule_Code09_MapTool_MapToolTest" size="large" />
            </group>
        </groups>
        <controls>
            <!-- add your controls here -->
            <!-- 在这里添加控件 -->
            <tool id="WineMonk_Demo_ProAppModule_Code09_MapTool_MapToolTest" caption="MapToolTest" className="WineMonk.Demo.ProAppModule.Code09_MapTool.MapToolTest" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonRed16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonRed32.png" condition="esri_mapping_mapPane">
                <tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
            </tool>
        </controls>
    </insertModule>
</modules>

11 ArcGIS Pro 嵌入式控件

11.1 添加控件

image-20240604133943119

image-20240604153753998

image-20240604151205450

11.2 Code

嵌入式控件需要搭配地图工具一起使用,需要多创建一个用来激活控件的MapTool,这里示例创建一个显示鼠标点击位置地理坐标的控件。

EmbeddableControlTest.xaml

<UserControl x:Class="WineMonk.Demo.ProAppModule.Code10_EmbeddableControl.EmbeddableControlTestView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:ui="clr-namespace:WineMonk.Demo.ProAppModule.Code10_EmbeddableControl"
             xmlns:extensions="clr-namespace:ArcGIS.Desktop.Extensions;assembly=ArcGIS.Desktop.Extensions"
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             d:DataContext="{Binding Path=ui.EmbeddableControlTestViewModel}">
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <extensions:DesignOnlyResourceDictionary Source="pack://application:,,,/ArcGIS.Desktop.Framework;component\Themes\Default.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
    <Grid>
        <TextBlock Text="{Binding Text}" HorizontalAlignment="Center" VerticalAlignment="Center" Margin="4"/>
    </Grid>
</UserControl>

EmbeddableControlTestViewModel.cs

using ArcGIS.Desktop.Framework.Controls;
using System.Xml.Linq;


namespace WineMonk.Demo.ProAppModule.Code10_EmbeddableControl
{
    internal class EmbeddableControlTestViewModel : EmbeddableControl
    {
        public EmbeddableControlTestViewModel(XElement options, bool canChangeOptions) : base(options, canChangeOptions) { }

        /// <summary>
        /// Text shown in the control.
        /// </summary>
        private string _text = "Embeddable Control";
        public string Text
        {
            get { return _text; }
            set
            {
                SetProperty(ref _text, value, () => Text);
            }
        }
    }
}

OpenControlMapTool.cs

using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Framework.Threading.Tasks;
using ArcGIS.Desktop.Mapping;
using System.Text;
using System.Threading.Tasks;

namespace WineMonk.Demo.ProAppModule.Code10_EmbeddableControl.MapTools
{
    internal class OpenControlMapTool : MapTool
    {
        public OpenControlMapTool()
        {
            //Set the tools OverlayControlID to the DAML id of the embeddable control
            OverlayControlID = "WineMonk_Demo_ProAppModule_Code10_EmbeddableControl_EmbeddableControlTest";
            //Embeddable control can be resized
            OverlayControlCanResize = true;
            //Specify ratio of 0 to 1 to place the control
            OverlayControlPositionRatio = new System.Windows.Point(0, 0); //top left
        }

        protected override void OnToolMouseDown(MapViewMouseButtonEventArgs args)
        {
            // On mouse down check if the mouse button pressed is the left mouse button. 
            // If it is handle the event.
            if (args.ChangedButton == System.Windows.Input.MouseButton.Left)
                args.Handled = true;
        }

        protected override Task HandleMouseDownAsync(MapViewMouseButtonEventArgs args)
        {
            //Get the instance of the ViewModel
            var vm = OverlayEmbeddableControl as EmbeddableControlTestViewModel;
            if (vm == null)
                return Task.FromResult(0);

            //Get the map coordinates from the click point and set the property on the ViewModel.
            return QueuedTask.Run(() =>
            {
                var mapPoint = ActiveMapView.ClientToMap(args.ClientPoint);
                var coords = GeometryEngine.Instance.Project(mapPoint, SpatialReferences.WGS84) as MapPoint;
                if (coords == null) return;
                var sb = new StringBuilder();
                sb.AppendLine($"X: {coords.X:0.000}");
                sb.Append($"Y: {coords.Y:0.000}");
                if (coords.HasZ)
                {
                    sb.AppendLine();
                    sb.Append($"Z: {coords.Z:0.000}");
                }
                vm.Text = sb.ToString();
            });
        }

        protected override Task OnToolActivateAsync(bool active)
        {
            return base.OnToolActivateAsync(active);
        }

        protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
        {
            return base.OnSketchCompleteAsync(geometry);
        }
    }
}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <tool refID="WineMonk_Demo_ProAppModule_Code10_EmbeddableControl_MapTools_OpenControlMapTool" size="large" />
            </group>
        </groups>
        <controls>
            <!-- add your controls here -->
            <!-- 在这里添加控件 -->
            <tool id="WineMonk_Demo_ProAppModule_Code10_EmbeddableControl_MapTools_OpenControlMapTool" caption="OpenControlMapTool" className="WineMonk.Demo.ProAppModule.Code10_EmbeddableControl.MapTools.OpenControlMapTool" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonRed16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonRed32.png" condition="esri_mapping_mapPane">
                <tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
            </tool>
        </controls>
    </insertModule>
</modules>
<categories>
    <updateCategory refID="esri_embeddableControls">
        <insertComponent id="WineMonk_Demo_ProAppModule_Code10_EmbeddableControl_EmbeddableControlTest" className="WineMonk.Demo.ProAppModule.Code10_EmbeddableControl.EmbeddableControlTestViewModel">
            <content className="WineMonk.Demo.ProAppModule.Code10_EmbeddableControl.EmbeddableControlTestView" />
        </insertComponent>
    </updateCategory>
</categories>

12 ArcGIS Pro 布局工具

12.1 添加控件

image-20240604153958836

image-20240604154034708

image-20240604154238006

12.2 Code

LayoutToolTest.cs

using ArcGIS.Core.Geometry;
using ArcGIS.Desktop.Layouts;
using ArcGIS.Desktop.Mapping;
using System.Threading.Tasks;

namespace WineMonk.Demo.ProAppModule.Code11_LayoutTool
{
    internal class LayoutToolTest : LayoutTool
    {
        public LayoutToolTest()
        {
            SketchType = SketchGeometryType.Rectangle;
        }
        protected override Task OnToolActivateAsync(bool active)
        {
            return base.OnToolActivateAsync(active);
        }
        protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
        {
            //TODO: Use geometry. Add graphic, select elements, etc.
            //QueuedTask.Run( () => {
            //  ActiveElementContainer.SelectElements(geometry, SelectionCombinationMethod.New, false);
            //});
            return base.OnSketchCompleteAsync(geometry);
        }
    }
}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
        <groups>
            <!-- comment this out if you have no controls on the Addin tab to avoid an empty group -->
            <!-- 如果您没有插件选项卡上的控件,请将其注释掉,以避免出现空组 -->
            <group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
                <!-- host controls within groups -->
                <!-- 组内主机控件 -->
                <tool refID="WineMonk_Demo_ProAppModule_Code11_LayoutTool_LayoutToolTest" size="large" />
            </group>
        </groups>
        <controls>
            <!-- add your controls here -->
            <!-- 在这里添加控件 -->
            <!--use condition="esri_layouts_layoutPane" to enable only in layout view-->
            <tool id="WineMonk_Demo_ProAppModule_Code11_LayoutTool_LayoutToolTest" caption="LayoutToolTest" className="WineMonk.Demo.ProAppModule.Code11_LayoutTool.LayoutToolTest" loadOnClick="true" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonRed16.png" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonRed32.png">
                <tooltip heading="Tooltip Heading">Tooltip text<disabledText /></tooltip>
            </tool>
        </controls>
    </insertModule>
</modules>

13 ArcGIS Pro 地图托盘按钮

13.1 添加控件

image-20240604154915615

image-20240604162417648

image-20240604162252661

13.2 Code

MapTrayButtonTest.cs

using ArcGIS.Desktop.Mapping;
using System.Windows.Controls;

namespace WineMonk.Demo.ProAppModule.Code12_MapTrayButton
{
    internal class MapTrayButtonTest : MapTrayButton
    {
        /// <summary>
        /// Invoked after construction, and after all DAML settings have been loaded. 
        /// Use this to perform initialization such as setting ButtonType.
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();

            // set the button type
            //  change for different button types
            ButtonType = TrayButtonType.PopupToggleButton;

            // ClickCommand is used for TrayButtonType.Button only
            // ClickCommand = new RelayCommand(DoClick);
        }
        /// <summary>
        /// Override to perform some button initialization.  This is called the first time the botton is loaded.
        /// </summary>
        protected override void OnButtonLoaded()
        {
            base.OnButtonLoaded();
        }

        #region TrayButtonType.Button
        private void DoClick()
        {
            // do something when the tray button is clicked
            // refresh the popup VM checked state
            if ((_popupVM != null) && (_popupVM.IsChecked != this.IsChecked))
                _popupVM.IsChecked = this.IsChecked;
        }
        #endregion

        #region TrayButtonType.ToggleButton / TrayButtonType.PopupToggleButton
        // 
        // this method fires when ButtonType = TrayButtonType.ToggleButton or PopupToggleButton
        // 

        /// <summary>
        /// Called when the toggle button check state changes
        /// </summary>
        protected override void OnButtonChecked()
        {
            // get the checked state
            var isChecked = this.IsChecked;

            // do something with the checked state
            // refresh the popup VM checked state
            if ((_popupVM != null) && (_popupVM.IsChecked != this.IsChecked))
                _popupVM.IsChecked = this.IsChecked;
        }
        #endregion

        #region TrayButtonType.PopupToggleButton

        // These methods fire when ButtonType = TrayButtonType.PopupToggleButton

        private MapTrayButtonTestPopupViewModel _popupVM = null;

        /// <summary>
        /// Construct the popup view and return it. 
        /// </summary>
        /// <returns></returns>
        protected override ContentControl ConstructPopupContent()
        {
            // set up the tray button VM
            _popupVM = new MapTrayButtonTestPopupViewModel()
            {
                Heading = this.Name,
                IsChecked = this.IsChecked
            };

            // return the UI with the datacontext set
            return new MapTrayButtonTestPopupView() { DataContext = _popupVM };
        }

        private bool _subscribed = false;

        /// <summary>
        /// Called when the popup is shown. 
        /// </summary>
        protected override void OnShowPopup()
        {
            base.OnShowPopup();
            // track property changes
            if (!_subscribed)
            {
                _popupVM.PropertyChanged += MapTrayButtonTestPopupViewModel_PropertyChanged;
                _subscribed = true;
            }
        }

        /// <summary>
        /// Called when the popup is hidden.
        /// </summary>
        protected override void OnHidePopup()
        {
            // cleanup
            if (_subscribed)
            {
                _popupVM.PropertyChanged -= MapTrayButtonTestPopupViewModel_PropertyChanged;
                _subscribed = false;
            }
            base.OnHidePopup();
        }

        private void MapTrayButtonTestPopupViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (_popupVM == null)
                return;
            // make sure MapTrayButton class has correct checked state when it changes on the VM
            if (e.PropertyName == nameof(MapTrayButtonTestPopupViewModel.IsChecked))
            {
                // Since we are changing IsChecked in OnButtonChecked
                //We don't want property notification to trigger (another) callback to OnButtonChecked
                this.SetCheckedNoCallback(_popupVM.IsChecked);
            }
        }

        // Provided to show you how to manually close the popup via code. 
        private void ManuallyClosePopup()
        {
            this.ClosePopup();
        }
        #endregion
    }
}

MapTrayButtonTestPopupView.xaml

<UserControl x:Class="WineMonk.Demo.ProAppModule.Code12_MapTrayButton.MapTrayButtonTestPopupView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WineMonk.Demo.ProAppModule.Code12_MapTrayButton"
             mc:Ignorable="d" 
             d:DataContext="{Binding Path=local.MapTrayButtonTestPopupViewModel}"
             d:DesignHeight="450" d:DesignWidth="800">
    <Border BorderThickness="1" BorderBrush="{DynamicResource Esri_Blue}">
        <StackPanel
                    Margin="1"
                    Width="Auto" Height="Auto"
                    Background="Transparent">
            <!--this is the header-->
            <CheckBox Style="{DynamicResource Esri_CheckboxTrayButtonHeader}"        
                      Foreground="{DynamicResource Esri_Blue}"
                      Background="{DynamicResource Esri_Gray105}"
                      IsChecked="{Binding IsChecked, Mode=TwoWay}" >
                <TextBlock Style="{DynamicResource Esri_TextBlockTrayButtonHeader}"
                           Text="{Binding Heading, Mode=OneWay}"/>
            </CheckBox>
            <!--content-->
        </StackPanel>
    </Border>
</UserControl>

MapTrayButtonTestPopupViewModel.cs

using ArcGIS.Desktop.Framework.Contracts;

namespace WineMonk.Demo.ProAppModule.Code12_MapTrayButton
{
    internal class MapTrayButtonTestPopupViewModel : PropertyChangedBase
    {
        /// <summary>
        /// Text shown near the top Map Tray UI.
        /// </summary>
        private string _heading = "MapTray";
        public string Heading
        {
            get => _heading;
            set => SetProperty(ref _heading, value);
        }

        private bool _isChecked;
        public bool IsChecked
        {
            get => _isChecked;
            set => SetProperty(ref _isChecked, value);
        }
    }
}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">      </insertModule>
</modules>
<categories>
    <updateCategory refID="esri_mapping_MapTrayButtons">
        <!-- 这里有个坑,插件自动生成的代码中,@className属性的值是类名,应该的类的完全限定名,如果添加了按钮,但是在界面没有显示,看一下是不是这个@className属性的原因 -->
        <insertComponent id="WineMonk_Demo_ProAppModule_Code12_MapTrayButton_MapTrayButtonTest" className="WineMonk.Demo.ProAppModule.Code12_MapTrayButton.MapTrayButtonTest">
            <content L_name="MapTrayButtonTest" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonRed32.png" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonRed16.png" L_tooltipHeading="MapTrayButtonTest" L_tooltip="This is a sample tray button" />
        </insertComponent>
    </updateCategory>
</categories>

14 ArcGIS Pro 布局托盘按钮

14.1 添加控件

image-20240604163037635

image-20240604163348628

image-20240604163310542

14.2 Code

LayoutTrayButtonTest.cs

using ArcGIS.Desktop.Layouts;
using ArcGIS.Desktop.Mapping;
using System.Windows.Controls;

namespace WineMonk.Demo.ProAppModule.Code13_LayoutTrayButton
{
    internal class LayoutTrayButtonTest : LayoutTrayButton
    {
        /// <summary>
        /// Invoked after construction, and after all DAML settings have been loaded. 
        /// Use this to perform initialization such as setting ButtonType.
        /// </summary>
        protected override void Initialize()
        {
            base.Initialize();

            // set the button type
            //  change for different button types
            ButtonType = TrayButtonType.PopupToggleButton;

            // ClickCommand is used for TrayButtonType.Button only
            // ClickCommand = new RelayCommand(DoClick);
        }

        /// <summary>
        /// Override to perform some button initialization.  This is called the first time the botton is loaded.
        /// </summary>
        protected override void OnButtonLoaded()
        {
            base.OnButtonLoaded();
        }


        #region TrayButtonType.Button
        private void DoClick()
        {
            // do something when the tray button is clicked
        }
        #endregion


        #region TrayButtonType.ToggleButton / TrayButtonType.PopupToggleButton
        // 
        // this method fires when ButtonType = TrayButtonType.ToggleButton or PopupToggleButton
        // 

        /// <summary>
        /// Called when the toggle button check state changes
        /// </summary>
        protected override void OnButtonChecked()
        {
            // get the checked state
            var isChecked = this.IsChecked;

            // do something with the checked state
            // refresh the popup VM checked state
            if ((_popupVM != null) && (_popupVM.IsChecked != this.IsChecked))
                _popupVM.IsChecked = this.IsChecked;
        }
        #endregion

        #region TrayButtonType.PopupToggleButton
        // 
        // These methods fire when ButtonType = TrayButtonType.PopupToggleButton
        // 

        private LayoutTrayButtonTestPopupViewModel _popupVM = null;

        /// <summary>
        /// Construct the popup view and return it. 
        /// </summary>
        /// <returns></returns>
        protected override ContentControl ConstructPopupContent()
        {
            // set up the tray button VM
            _popupVM = new LayoutTrayButtonTestPopupViewModel()
            {
                Heading = this.Name,
                IsChecked = this.IsChecked
            };

            // return the UI with the datacontext set
            return new LayoutTrayButtonTestPopupView() { DataContext = _popupVM };
        }

        private bool _subscribed = false;

        /// <summary>
        /// Called when the popup is shown. 
        /// </summary>
        protected override void OnShowPopup()
        {
            base.OnShowPopup();
            // track property changes
            if (!_subscribed)
            {
                _popupVM.PropertyChanged += LayoutTrayButtonTestPopupViewModel_PropertyChanged;
                _subscribed = true;
            }
        }

        /// <summary>
        /// Called when the popup is hidden.
        /// </summary>
        protected override void OnHidePopup()
        {
            // cleanup
            if (_subscribed)
            {
                _popupVM.PropertyChanged -= LayoutTrayButtonTestPopupViewModel_PropertyChanged;
                _subscribed = false;
            }
            base.OnHidePopup();
        }

        private void LayoutTrayButtonTestPopupViewModel_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (_popupVM == null)
                return;
            // make sure MapTrayButton class has correct checked state when it changes on the VM
            if (e.PropertyName == nameof(LayoutTrayButtonTestPopupViewModel.IsChecked))
            {
                // Since we are changing IsChecked in OnButtonChecked
                //We don't want property notification to trigger (another) callback to OnButtonChecked
                this.SetCheckedNoCallback(_popupVM.IsChecked);
            }
        }

        // Provided to show you how to manually close the popup via code. 
        private void ManuallyClosePopup()
        {
            this.ClosePopup();
        }
        #endregion
    }
}

LayoutTrayButtonTestPopupView.xaml

<UserControl x:Class="WineMonk.Demo.ProAppModule.Code13_LayoutTrayButton.LayoutTrayButtonTestPopupView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:local="clr-namespace:WineMonk.Demo.ProAppModule.Code13_LayoutTrayButton"
             mc:Ignorable="d" 
             d:DataContext="{Binding Path=local.LayoutTrayButtonTestPopupViewModel}"
             d:DesignHeight="450" d:DesignWidth="800">
    <Border BorderThickness="1" BorderBrush="{DynamicResource Esri_Blue}">
        <StackPanel
                    Margin="1"
                    Width="Auto" Height="Auto"
                    Background="Transparent">
            <!--this is the header-->
            <CheckBox Style="{DynamicResource Esri_CheckboxTrayButtonHeader}"        
                      Foreground="{DynamicResource Esri_Blue}"
                      Background="{DynamicResource Esri_Gray105}"
                      IsChecked="{Binding IsChecked, Mode=TwoWay}" >
                <TextBlock Style="{DynamicResource Esri_TextBlockTrayButtonHeader}"
                           Text="{Binding Heading, Mode=OneWay}"/>
            </CheckBox>
            <!--content-->
        </StackPanel>
    </Border>
</UserControl>

LayoutTrayButtonTestPopupViewModel.cs

using ArcGIS.Desktop.Framework.Contracts;

namespace WineMonk.Demo.ProAppModule.Code13_LayoutTrayButton
{
    internal class LayoutTrayButtonTestPopupViewModel : PropertyChangedBase
    {
        /// <summary>
        /// Text shown near the top Map Tray UI.
        /// </summary>
        private string _heading = "LayoutTray";
        public string Heading
        {
            get => _heading;
            set => SetProperty(ref _heading, value);
        }

        private bool _isChecked;
        public bool IsChecked
        {
            get => _isChecked;
            set => SetProperty(ref _isChecked, value);
        }
    }
}

Config.daml

<modules>
    <insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">      </insertModule>
</modules>
<categories>
    <updateCategory refID="esri_layouts_LayoutTrayButtons">
        <!-- 这里有个坑,插件自动生成的代码中,@className属性的值是类名,应该的类的完全限定名,如果添加了按钮,但是在界面没有显示,看一下是不是这个@className属性的原因 -->
        <insertComponent id="WineMonk_Demo_ProAppModule_Code13_LayoutTrayButton_LayoutTrayButtonTest" className="WineMonk.Demo.ProAppModule.Code13_LayoutTrayButton.LayoutTrayButtonTest">
            <content L_name="LayoutTrayButtonTest" largeImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGreen32.png" smallImage="pack://application:,,,/ArcGIS.Desktop.Resources;component/Images/GenericButtonGreen16.png" L_tooltipHeading="LayoutTrayButtonTest" L_tooltip="This is a sample tray button" />
        </insertComponent>
    </updateCategory>
</categories>

相关推荐

最近更新

  1. TCP协议是安全的吗?

    2024-06-17 12:58:02       16 阅读
  2. 阿里云服务器执行yum,一直下载docker-ce-stable失败

    2024-06-17 12:58:02       16 阅读
  3. 【Python教程】压缩PDF文件大小

    2024-06-17 12:58:02       15 阅读
  4. 通过文章id递归查询所有评论(xml)

    2024-06-17 12:58:02       18 阅读

热门阅读

  1. 掌握现代C++的模板元编程类型检测技术

    2024-06-17 12:58:02       7 阅读
  2. LINUX 进阶 3.1

    2024-06-17 12:58:02       7 阅读
  3. 小程序页面路由传参方法

    2024-06-17 12:58:02       7 阅读
  4. VIRT高是因为分配了太多地址空间导致。

    2024-06-17 12:58:02       6 阅读
  5. RabbitMQ消息的可靠传输和防止消息丢失

    2024-06-17 12:58:02       6 阅读
  6. 品质主管的面试题目

    2024-06-17 12:58:02       6 阅读
  7. dayjs将星期的第一天设置为周一

    2024-06-17 12:58:02       4 阅读
  8. 5、存储管理

    2024-06-17 12:58:02       4 阅读
  9. 0018__关于字体和字体微调(Hinting )的知识

    2024-06-17 12:58:02       11 阅读