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





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>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<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>
<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>



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>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<buttonPalette refID="WineMonk_Demo_ProAppModule_Code02_ButtonPalette_ButtonPaletteTest" />
group>
groups>
<controls>
<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>



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>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<menu refID="WineMonk_Demo_ProAppModule_Code03_Menu_MenuTest" size="middle" />
group>
groups>
<controls>
<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>



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>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<splitButton refID="WineMonk_Demo_ProAppModule_Code04_SplitButton_SplitButtonTest" />
group>
groups>
<controls>
<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>



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
Config.daml
<modules>
<insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
<groups>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<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>



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
Config.daml
<modules>
<insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1">
<groups>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<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>



ComboBoxTest.cs
using ArcGIS.Desktop.Framework.Contracts;
using System.Linq;
namespace WineMonk.Demo.ProAppModule.Code07_ComboBox
{
///
/// Represents the ComboBox
///
internal class ComboBoxTest : ComboBox
{
private bool _isInitialized;
///
/// Combo Box constructor
///
public ComboBoxTest()
{
UpdateCombo();
}
///
/// Updates the combo box with all the items.
///
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
}
///
/// The on comboBox selection change event.
///
/// The newly selected combo box item
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>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<comboBox refID="WineMonk_Demo_ProAppModule_Code07_ComboBox_ComboBoxTest" />
group>
groups>
<controls>
<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>



CustomControlTest.xaml
CustomControlTestViewModel.cs
using ArcGIS.Desktop.Framework.Contracts;
namespace WineMonk.Demo.ProAppModule.Code08_CustomControl
{
internal class CustomControlTestViewModel : CustomControl
{
///
/// Text shown in the control.
///
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>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<customControl refID="WineMonk_Demo_ProAppModule_Code08_CustomControl_CustomControlTest" size="large" />
group>
groups>
<controls>
<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>



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>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<tool refID="WineMonk_Demo_ProAppModule_Code09_MapTool_MapToolTest" size="large" />
group>
groups>
<controls>
<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>



嵌入式控件需要搭配地图工具一起使用,需要多创建一个用来激活控件的MapTool,这里示例创建一个显示鼠标点击位置地理坐标的控件。
EmbeddableControlTest.xaml
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) { }
///
/// Text shown in the control.
///
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>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<tool refID="WineMonk_Demo_ProAppModule_Code10_EmbeddableControl_MapTools_OpenControlMapTool" size="large" />
group>
groups>
<controls>
<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>



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>
<group id="WineMonk_Demo_ProAppModule_Group1" caption="Group 1" appearsOnAddInTab="false">
<tool refID="WineMonk_Demo_ProAppModule_Code11_LayoutTool_LayoutToolTest" size="large" />
group>
groups>
<controls>
<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>



MapTrayButtonTest.cs
using ArcGIS.Desktop.Mapping;
using System.Windows.Controls;
namespace WineMonk.Demo.ProAppModule.Code12_MapTrayButton
{
internal class MapTrayButtonTest : MapTrayButton
{
///
/// Invoked after construction, and after all DAML settings have been loaded.
/// Use this to perform initialization such as setting ButtonType.
///
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);
}
///
/// Override to perform some button initialization. This is called the first time the botton is loaded.
///
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
//
///
/// Called when the toggle button check state changes
///
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;
///
/// Construct the popup view and return it.
///
///
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;
///
/// Called when the popup is shown.
///
protected override void OnShowPopup()
{
base.OnShowPopup();
// track property changes
if (!_subscribed)
{
_popupVM.PropertyChanged += MapTrayButtonTestPopupViewModel_PropertyChanged;
_subscribed = true;
}
}
///
/// Called when the popup is hidden.
///
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
MapTrayButtonTestPopupViewModel.cs
using ArcGIS.Desktop.Framework.Contracts;
namespace WineMonk.Demo.ProAppModule.Code12_MapTrayButton
{
internal class MapTrayButtonTestPopupViewModel : PropertyChangedBase
{
///
/// Text shown near the top Map Tray UI.
///
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">
<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>



LayoutTrayButtonTest.cs
using ArcGIS.Desktop.Layouts;
using ArcGIS.Desktop.Mapping;
using System.Windows.Controls;
namespace WineMonk.Demo.ProAppModule.Code13_LayoutTrayButton
{
internal class LayoutTrayButtonTest : LayoutTrayButton
{
///
/// Invoked after construction, and after all DAML settings have been loaded.
/// Use this to perform initialization such as setting ButtonType.
///
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);
}
///
/// Override to perform some button initialization. This is called the first time the botton is loaded.
///
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
//
///
/// Called when the toggle button check state changes
///
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;
///
/// Construct the popup view and return it.
///
///
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;
///
/// Called when the popup is shown.
///
protected override void OnShowPopup()
{
base.OnShowPopup();
// track property changes
if (!_subscribed)
{
_popupVM.PropertyChanged += LayoutTrayButtonTestPopupViewModel_PropertyChanged;
_subscribed = true;
}
}
///
/// Called when the popup is hidden.
///
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
LayoutTrayButtonTestPopupViewModel.cs
using ArcGIS.Desktop.Framework.Contracts;
namespace WineMonk.Demo.ProAppModule.Code13_LayoutTrayButton
{
internal class 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
<modules>
<insertModule id="WineMonk_Demo_ProAppModule_Module" className="Module1" autoLoad="false" caption="Module1"> insertModule>
modules>
<categories>
<updateCategory refID="esri_layouts_LayoutTrayButtons">
<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>