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

news2024/12/24 10:26:42

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>

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

人工智能的潜在威胁:罗曼·扬波尔斯基对AGI的警示

随着科技的飞速发展&#xff0c;人工智能&#xff08;AI&#xff09;技术正迅速成为人类社会不可或缺的一部分。然而&#xff0c;随着人工智能技术的发展&#xff0c;一些科学家对其潜在的危险表示了担忧。本文将深入探讨计算机科学家罗曼扬波尔斯基对人工智能特别是人工通用智…

Java springboot社区团购系统源码

Java springboot社区团购系统源码-012 环境要求 1.运行环境&#xff1a;最好是java jdk1.8,我们在这个平台上运行的。其他版本理论上也可以。 2.IDE环境&#xff1a;IDEA,Eclipse,Myeclipse都可以。推荐IDEA; 3.tomcat环境&#xff1a;Tomcat7.x,8.X,9.x版本均可 4.硬件环境…

计算机组成原理(六)

0x12345678和12345678H都是指同一个十六进制,也就是12345678&#xff0c;不过是不同的编程语言的写法而已 具体来说&#xff0c;如果有 n 根地址线&#xff0c;计算机可以寻址的内存空间大小是 2^n 字节。 24根地址线&#xff1a; 如果一个系统有24根地址线&#xff0c;意味着它…

上位机图像处理和嵌入式模块部署(f407 mcu类项目开发特点)

【 声明&#xff1a;版权所有&#xff0c;欢迎转载&#xff0c;请勿用于商业用途。 联系信箱&#xff1a;feixiaoxing 163.com】 和soc相比较&#xff0c;mcu的项目规模一般不算大。因为&#xff0c;soc项目中&#xff0c;从规划、硬件开发、驱动、应用端、服务器端到测试&…

【论文阅读】-- Omnisketch:高效的多维任意谓词高速流分析

Omnisketch&#xff1a;高效的多维任意谓词高速流分析 摘要1 引言2 预备知识及相关工作3 OMNISKETCH&#xff1a;使用任意谓词估计频率3.1 Sketch S0&#xff1a;Count-Min with rid-sets 用于估计带有谓词的查询3.2 Sketch S1 &#xff08;OmniSketch&#xff09;&#xff1a;…

conda虚拟环境报错总结

创建conda虚拟环境 文章前景&#xff08;小白篇&#xff09;为什么要安装Anaconda&#xff1f;&#xff1f;&#xff1f; Conda创建虚拟环境遇到的错误总结错误1&#xff1a;jupyter 里面没有显示我的虚拟环境怎么办&#xff1f;错误2&#xff1a;配置pycharm的时候conda虚拟环…

【数字化转型,销售先行】销售的数字化转型需要做哪些工作?

引言&#xff1a;销售进行数字化转型的背景主要包括市场环境的快速变化、新技术发展的推动、企业发展的需求以及数据驱动决策的需求。这些背景因素共同促使企业加快数字化转型步伐&#xff0c;以适应市场变化、提升竞争力并实现可持续发展。 销售的数字化转型包含哪些内容&…

python的np.array()函数

1、创建数组 2、 与矩阵相关的函数 3、与排序相关的函数 4、 一元计算函数 5、 多元计算函数 6、 与文件读写相关的函数 7、与数组形状、属性相关的函数 8、 常用计算函数 9、 数组选取:切片和索引 10、np.random相关函数 Numpy常用的20个函数 一…

集成学习 #数据挖掘 #Python

集成学习是一种机器学习方法&#xff0c;它通过结合多个模型的预测结果来提高整体性能和稳定性。这种方法的主要思想是“集合智慧”&#xff0c;通过将多个模型&#xff08;比如决策树、随机森林、梯度提升机等&#xff09;的预测集成起来&#xff0c;可以减少单个模型的过拟合…

重新安装TortoiseGit后提示权限错误问题解决

今天在Windows11系统中下载安装使用TortoiseGit可视化Git工具&#xff0c;进行代码提交管理。 由于电脑之前是一位开发人员在使用&#xff0c;所以曾经安装使用过这个工具。 重新安装好软件后&#xff0c;在coding网站中复制代码路径后&#xff0c;在本地目录通过鼠标右键选择…

视频生成模型 Dream Machine 开放试用;微软将停止 Copilot GPTs丨 RTE 开发者日报 Vol.224

开发者朋友们大家好&#xff1a; 这里是 「RTE 开发者日报」 &#xff0c;每天和大家一起看新闻、聊八卦。我们的社区编辑团队会整理分享 RTE&#xff08;Real-Time Engagement&#xff09; 领域内「有话题的 新闻 」、「有态度的 观点 」、「有意思的 数据 」、「有思考的 文…

React 渲染函数render、初始化函数、更新函数运行了两次,原因为何,如何解决? React.StrictMode

文章目录 Intro官网解释解决另一篇官网文章——初始化函数或更新函数运行了两次 Intro 我在用 react 写一个 demo &#xff0c;当我在某个自定义组件的 return 语句之前加上一句log之后&#xff0c;发现&#xff1a;每次页面重新渲染&#xff0c;该行日志都打印了两次&#xf…

加油卡APP开发,汽车加油便捷新方式

随着生活水平的提高&#xff0c;人们对汽车的需求量不断上升&#xff0c;加油成为了大众生活中不可缺少的开销&#xff0c;为节省开销&#xff0c;如何优惠加油成为了大众所追求的事。因此&#xff0c;越来越多的加油卡APP成为了汽车加油市场的发展“主流”。在汽车加油规模上升…

数据结构错题答案汇总

王道学习 第一章 绪论 1.1 3.A 数据的逻辑结构是从面向实际问题的角度出发的&#xff0c;只采用抽象表达方式&#xff0c;独立于存储结构&#xff0c;数据的存储方式有多种不同的选择;而数据的存储结构是逻辑结构在计算机上的映射&#xff0c;它不能独立于逻辑结构而存在。数…

PFC旁路二极管、继电器驱动电路以及PFC主功率

R001和R002以及R003三个电阻作用是限放X电容上的电 整流桥串联两个BJ1和BJ2 电容C3:给整流桥储能&#xff0c;给后续llc供电 PFC工作是正弦波上叠加高频电流 PFC功率部分 2个PFC电感&#xff08;选择两个磁芯骨架小&#xff0c;有利于散热&#xff09;、2个续流二极管&…

Mac 下载并激活IDEA

1.https://3.jetbra.in 打开这个网站,点击第一个网速比较快的连接 2.在新页面顶部有一个蓝色的下载链接文字< jetbra.zip(20220801) >点击下载 3.步骤2打开的页面不要关闭后面还有用 4.在idea官网下载idea对应的版本 https://www.jetbrains.com/idea/download/other.htm…

linux配置用户

一&#xff0c;安装sudo与确保在管理员用户下 apt update apt install sudo -y 切换用户&#xff1a;密码不会显示&#xff0c;一个个输入然后回车。//图中是zfxt-->Stable用户切换 su root //root为用户名 以其他用户执行命令&#xff1a; su root ping baidu.com //su…

不测评不知道,该这款主食冻干嚣张!PR、希喂、扑呀真实测评

主食冻干喂养越来越火了&#xff0c;除了知名的“四大金刚”K9、VE、SC、PR之外&#xff0c;也有像希喂、扑呀这类以营养、高肉含量为切入点的新锐品牌&#xff0c;各大猫粮商更是纷纷推出了自家的主食冻干产品。目前关于主食冻干的讨论也很多&#xff0c;但大多数还是以科普和…

恭喜!X医生斩获英国伦敦大学学院访问学者邀请函

伦敦大学学院&#xff08;University College London&#xff0c;简称&#xff1a;UCL&#xff09;&#xff0c;1826年创立于英国伦敦&#xff0c;是一所公立研究型大学。伦敦大学联盟的创校学院、罗素大学集团和欧洲研究型大学联盟创始成员&#xff0c;也是金三角名校和G5之一…

5.1 Python 函数的参数类型

1. 实参与形参 形参: 函数定义阶段, 括号内定义的参数名(变量名), 形参的表现形式只有一种就是参数命. 实参: 函数调用阶段, 括号内传入的参数值(变量值), 实参的表现形式有很多种(核心: 可以引用到值).两者之间的关系: 函数调用阶段 --> 实参的值绑定给形参名. 函数调用完…