ArcGIS Pro SDK for.net: Advanced User Interfaces in Add-ins Wolfgang Kaiser
Framework Elements - Recap Any Framework Element is an extensibility point - Controls (Button, Tool, and variants) - Hosted on Ribbons, Menus, Galleries - Checkbox, Combobox, Label Control, Custom Controls - Tabs, Tab Groups - Toolbars - Menus, Context Menus - Panes - Dockpanes - Galleries - Property Sheets All Elements have a definition within DAML
Framework Elements - Recap Majority of Framework Elements are represented by Visual Studio Item templates - Automates generation of DAML - Add relevant code-behind files to the project Some Framework Elements need a much higher degree of customization (than a template can provide) - Custom Control - Gallery - Dynamic Context Menus Note: Complete element reference is here: https://github.com/esri/arcgis-pro-sdk/wiki/proconcepts-framework
Demo Pro SDK Project and Item Templates
CustomControl Hosted on the Ribbon. - You require a more sophisticated control beyond a single button, split button, or individual control - Examples: CustomAnimation sample TimeNavigation sample
CustomControl Run CustomControl item template - Will create DAML entry and a UserControl and ViewModel for CustomControl implementation UI goes in the CustomControl1.xaml Code behind in the CustomControl1ViewModel.cs - Becomes similar to Dockpane, Property Sheet, Embeddable Control
CustomControl UI Content can be any mix of WPF controls - You are responsible for all Binding - Provide the appropriate properties in your ViewModel - Keep sizing appropriate for hosting on the ribbon. - Small group = 22 pixels height - Large group = 68 pixels height - There is no OnClick (eg, as with a button). - Events will be generated directly from your WPF controls
Demo Custom Control Time Navigation
Gallery Container control, displays a collection of related items in rows and columns If too many items are in the gallery an expand arrow is provided Contents are populated at run time Individual gallery items are modelled using GalleryItem class Style with a GalleryTemplate.xaml
Gallery Shown as a split-button with a dropdown that exposes gallery Do any content initialization in the Gallery code-behind OnDropDownOpened - GalleryItems are created at runtime class Gallery1 : Gallery { protected override void OnDropDownOpened() { //Handle populating gallery content Initialize(); } private void Initialize() { //TODO: Init content Whenever a gallery item is clicked, the Gallery OnClick is called with the clicked GalleryItem as a parameter
Gallery DAML gallery definition: <!-- Config.daml <galleries> <gallery id="timenavigation_bkmgallery"... rows="4" itemsinrow="4" # of rows and columns datatemplatefile=...timebkmgallerytemplate.xaml" Data template templateid="timebkmitemtemplate"> Resource key <button refid="esri_mapping_createbookmark" /> Child button </gallery> <! TimeBkmGalleryTemplate.xaml <DataTemplate x:key="timebkmitemtemplate"> <StackPanel Orientation="Vertical... <Image Source="{Binding Icon}... <TextBlock Text="{Binding Text}...
Gallery Galleries can also be defined as inline Inline shows gallery items directly in the ribbon (not in a dropdown) Set the inline attribute on the gallery reference to true (Done automatically for you via the inline gallery template) <groups> <group id= Time_Group" caption="map Time"> <gallery refid="time_inlinegallery1" inline="true" size="large"/> </group>
Dynamic Menus Use when a dynamically populated menu is required - i.e. Content is not known until the menu is shown 1. Can be used as a dynamic context menu - e.g. in conjunction with MapTool to create a custom context menu with MapView 2. Can be used as dynamic content for another (parent) menu No Helper SDK Item templates
Dynamic Menus - Procedure 1. As a Context Menu 1. Declare a DynamicMenu element in DAML 2. Implement DynamicMenu derived class in code-behind - Populate menu content in the DynamicMenu.Popup callback 3. Create the menu using FrameworkApplication.CreateContextMenu - Second parameter is the name of a property that provides a System.Windows.Point for the menu location 4. Show the menu by setting isopen = true on your context menu - contextmenu.isopen = true triggers OnPopup() callback - Complete code next slide
Dynamic Menus Implement derived class Step 1 DAML <dynamicmenu id="dynamicmenu1" classname=..." caption=..." /> Step 2 Implement derived class internal class DynamicFeatureSelectionMenu : DynamicMenu { //Define delegate to be called when your menu items are clicked public delegate void FeatureSelectedDelegate(BasicFeatureLayer layer, long oid); private readonly FeatureSelectedDelegate _delegate = null; _delegate = OnFeatureSelected; //assignment is elsewhere e.g. constructor... //Populate your menu items use DynamicMenu.Add overloads" protected override void OnPopup() { foreach (var selitem in Module1.CurrentFeatureSelection) { this.add($"{selitem.layer.name}: {selitem.oid}", null, false, true, false, _delegate, selitem.layer, selitem.oid); //Your delegate void OnFeatureSelected(BasicFeatureLayer layer, long oid) { var mapview = MapView.Active; mapview?.flashfeature(layer, oid); //etc,etc
Dynamic Menus Invoke As a Context Menu - Show the menu using FrameworkApplication.CreateContextMenu - Setting isopen=true triggers Popup callback //e.g. in your maptool internal class FeatureSelectionDynamic : MapTool { protected override Task<bool> OnSketchCompleteAsync(Geometry geometry) { //TODO your logic, workflow, etc. //Step 3: Create the dynamic menu var contextmenu = FrameworkApplication.CreateContextMenu("DynamicMenu1"); contextmenu.datacontext = this; //optional set data context if needed contextmenu.closed += (o, e) => { //TODO any clean up you need on menu close }; //Step 4 set menu visible, trigger OnPopup() callback contextmenu.isopen = true;
Dynamic Menus - Procedure 2. As Content ~within~ another menu 1. Add a dynamicmenu refid as a child in the parent menu - By default, dynamic content is shown as a side-pull from the parent menu - Set inline=true to add your content directly (i.e. no side-pull) <dynamicmenu id="dynamicmenu1" classname= MyDynamicMenu" caption=..." />... <menu id="mainmenu" caption="mainmenu"> <button refid="somemenubutton"/> <dynamicmenu refid= DynamicMenu1" inline="true"/><! inline, not side-pull <button refid="othermenubutton" separator="true"/> </menu> 2. Implement DynamicMenu derived class in code-behind as before 3. Popup callback will be called whenever the parent menu is shown - NO need to manually call FrameworkApplication.CreateContextMenu
Demo Dynamic Menu
Add-in Styling New at 1.4 is Dark Theme. In order for your Add-ins to blend when theme is toggled they must be styled correctly - Will also support High Contrast mode for accessibility - Note: It is not required that your Add-ins blend though is desirable in most cases
General Rules Use ESRI Styles (and Colors) to the greatest extent possible for: - Text (most important) - Buttons (most important) - Other controls: TextBox, Listbox, Combobox, Datagrid, TreeView, Border, etc. <TextBlock Text="{Binding Name}" Style="{DynamicResource RegularText}" /> <Button x:name= MyButton" Style="{DynamicResource Esri_SimpleBorderlessButton}" <Image Source="{Binding Thumbnail}"> <Image.Effect> <DropShadowEffect Color="{DynamicResource Esri_Color_Gray145}" BlurRadius="14" ShadowDepth="4.5 /> </Image.Effect> </Image>
General Rules Prefer use of DynamicResources (avoids compilation issues with StaticResources) All controls will inherit a basic default style from the Pro Framework if one is not. assigned - Default style will correctly style all elements in Default, Dark, or High Contrast modes - Avoid using System colors in XAML. - They will not flip to dark alternatives when the theme changes - Esri styles and colors flip automatically for you. Avoid setting background colors on User Controls. - Setting background color to transparent can solve most issues allowing background color of host pane to show through
Examples Panes already come with the correct background color
Examples Dialogs at 1.4 inherit from ArcGIS.Desktop.Framework.Controls.ProWindow - Has correct background - Correct title bar styling - Avoid directly inheriting from System.Windows.Window
Examples Galleries will inherit the correct style from the base Actipro control - BUT you are responsible for correctly styling gallery items - Use ESRI_Styles!
Examples Text styles using Esri styles ensures that the color is always correct in Default or Dark themes
Examples Incorrect text styling. Note how the incorrect text color stayed black in Dark theme.
Styling Demo
Styling Resources At 1.4: All Pro samples have been styled correctly for Default, Dark theme, High Contrast - Examine how they are styled - https://github.com/esri/arcgis-pro-sdk-community-samples Concept documentation on Github will be enhanced with styling reference - HowTo guidelines - List of text styles - List of control styles - List of colors ProGuides on Github - Styling walkthroughs
Thank You to Our Sponsors