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>

LayoutTrayButtonTestPopupViewModel : PropertyChangedBase
{
///
/// Text shown near the top Map Tray UI.
///
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**

```xml
<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>

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/705652.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

如何从零训练多模态大模型(预训练方向)

节前&#xff0c;我们星球组织了一场算法岗技术&面试讨论会&#xff0c;邀请了一些互联网大厂朋友、参加社招和校招面试的同学. 针对算法岗技术趋势、大模型落地项目经验分享、新手如何入门算法岗、该如何准备、面试常考点分享等热门话题进行了深入的讨论。 汇总合集&…

所爱隔山海,上海婚恋交友app开发,我奔向你

每每讲到婚恋&#xff0c;就有感叹“难”的声音&#xff0c;在婚恋市场上&#xff0c;到处充斥者“难”的声音&#xff0c;更有胜者&#xff0c;甚至发出了“难于上青天”的感叹。在婚恋市场蹉跎浮沉的青年俊女们&#xff0c;越挫越勇&#xff0c;向着爱的呼唤&#xff0c;一次…

Java工具-实现无损png转换jpg格式

目录 1、背景说明 2、通过代码实现格式转换 3、无损转化 4、说明 读取 PNG 图像&#xff1a; 创建空的 JPG 图像&#xff1a; 绘制 PNG 图像到 JPG 图像&#xff1a; 设置 JPG 图片压缩质量&#xff1a; 写入 JPG 文件并关闭流&#xff1a; 5、jpg转png 1、背景说明 …

Opencv图像梯度计算

Opencv图像梯度计算 Sobel算子 可以理解为是做边缘检测的一种方法。 首先说明自己对图像梯度的简单理解&#xff1a;简单理解就是图像的颜色发生变化的边界区域在X方向和Y方向上的梯度值 Gx Gy 而Gx和Gy处的梯度的计算—使用下面的公式来进行计算。 G x [ − 1 0 1 − 2 0 …

计算机网络(5) ARP协议

什么是ARP 地址解析协议&#xff0c;即ARP&#xff08;Address Resolution Protocol&#xff09;&#xff0c;是根据IP地址获取物理地址的一个TCP/IP协议。主机发送信息时将包含目标IP地址的ARP请求广播到局域网络上的所有主机&#xff0c;并接收返回消息&#xff0c;以此确定…

【MySQL】mysql中常见的内置函数(日期、字符串、数学函数)

文章目录 案例表日期函数字符串函数数学函数其他函数 案例表 emp students 表 exam_result 表 日期函数 注意current_time和now的区别 案例一&#xff1a; 创建一张表用来记录生日&#xff0c;表结构如下 添加日期&#xff1a; insert tmp (birthday) values (2003-01-3…

香港CN2线路回国加速CDN介绍

随着互联网的迅猛发展&#xff0c;跨境数据传输的需求日益增加。尤其对于中国内地用户来说&#xff0c;访问海外网站和应用时&#xff0c;常常会面临网络延迟高、加载速度慢的问题。为了优化这一体验&#xff0c;香港 CN2 线路回国加速 CDN 成为了许多企业和个人的首选解决方案…

从Log4j和Fastjson RCE漏洞认识jndi注入

文章目录 前言JNDI注入基础介绍靶场搭建漏洞验证注入工具 log4j RCE漏洞分析漏洞靶场检测工具补丁绕过 Fastjson RCE漏洞分析漏洞靶场检测工具补丁绕过 总结 前言 接着前文的学习《Java反序列化漏洞与URLDNS利用链分析》&#xff0c;想了解为什么 Fastjson 反序列化漏洞的利用…

Java中的方法重写与重载

在Java编程语言中&#xff0c;方法重写&#xff08;Override&#xff09;和方法重载&#xff08;Overload&#xff09;是实现代码多态性的两种基本方式。它们允许程序员以多种方式使用相同的方法名&#xff0c;增加了程序的可读性和可重用性&#xff0c;但它们的应用场景和规则…

Nginx+KeepAlived高可用负载均衡集群的部署

目录 一.KeepAlived补充知识 1.一个合格的群集应该具备的特点 2.健康检查&#xff08;探针&#xff09;常用的工作方式 3.相关面试问题 问题1 问题2 二.Keepealived脑裂现象 1.现象 2.原因 硬件原因 运用配置原因 3.解决 4.预防 方法1 方法2 方法3 方法4 三.…

【Spine学习04】之让角色动起来

1、切换左上角模式&#xff1a;设置改为动画 2、选择两个手臂的大臂节点 3、打开勾选自动关键帧按钮 4、开始K帧&#xff1a; Space空格可以快捷查看小黄人所有关键帧

英语翻译人工翻译优势

在全球化的时代&#xff0c;跨文化交流至关重要&#xff0c;而翻译则是连接不同语言和文化的重要桥梁。尽管近年来人工智能翻译取得了显著进展&#xff0c;但人工翻译的需求仍然无可替代&#xff0c;尤其是在专业和技术翻译领域。下面从专业角度阐述人工翻译相较于人工智能翻译…

python如何终止程序运行

方法1&#xff1a;采用sys.exit(0)&#xff0c;正常终止程序&#xff0c;从图中可以看到&#xff0c;程序终止后shell运行不受影响。 方法2&#xff1a;采用os._exit(0)关闭整个shell&#xff0c;从图中看到&#xff0c;调用sys._exit(0)后整个shell都重启了&#xff08;RESTAR…

[c++刷题]贪心算法.N01

题目如上: 首先通过经验分析&#xff0c;要用最少的减半次数&#xff0c;使得数组总和减少至一半以上&#xff0c;那么第一反应就是每次都挑数组中最大的数据去减半&#xff0c;这样可以是每次数组总和值减少程度最大化。 代码思路:利用大根堆去找数据中的最大值&#xff0c;…

VScode中连接并使用docker容器

前提条件&#xff1a; 1.在windows下安装Docker Desktop(方法可见下面的教程) Docker Desktop 安装使用教程-CSDN博客 2.在vscode安装3个必备的插件 3.先在ubuntu中把docker构建然后运行 4.打开vscode&#xff0c;按下图顺序操作 调试好之后上传到git上&#xff0c;然后后面…

李宏毅深度学习01——基本概念简介

视频链接 基本概念 Regression&#xff08;回归&#xff09;&#xff1a; 类似于填空 Classification&#xff08;分类&#xff09;&#xff1a; 类似于选择 Structure Learning&#xff08;机器学习&#xff09;&#xff1a; &#xff1f;&#xff1f; 机器学习找对应函数…

字符串排序-第13届蓝桥杯省赛Python真题精选

[导读]&#xff1a;超平老师的Scratch蓝桥杯真题解读系列在推出之后&#xff0c;受到了广大老师和家长的好评&#xff0c;非常感谢各位的认可和厚爱。作为回馈&#xff0c;超平老师计划推出《Python蓝桥杯真题解析100讲》&#xff0c;这是解读系列的第82讲。 字符串排序&#…

SSH协议

SSH协议简介 SSH&#xff08;Secure Shell&#xff09;是一种网络安全协议&#xff0c;用于在不安全的网络环境中提供加密的远程登录和其他网络服务。它通过加密和认证机制实现安全的访问和文件传输等业务&#xff0c;是Telnet、FTP等不安全远程shell协议的安全替代方案。 SSH协…

HSP_08章 断点调试

P100 断点调试 1. 基本介绍 一个实际场景 在开发中&#xff0c;新手程序员在查找错误时&#xff0c;这时有经验的程序员就会提示&#xff0c;可以用断点调试&#xff0c;一步一步的看源码执行的过程, 从而发现错误所在。 断点调试介绍 -基本介绍 2. 函数的调试

使用Ventoy制作U盘启动安装系统

简介 Ventoy是一个制作可启动U盘的开源工具。 无需反复地格式化U盘。你只要制作一次U盘启动盘&#xff0c;后面你只需要把 ISO/WIM/IMG/VHD(x)/EFI 等类型的系统镜像文件直接拷贝到U盘里面就可以启动了&#xff0c;无需其他操作。可以一次性拷贝很多个不同类型的镜像文件&…