290 likes | 398 Views
ArcGIS Pro SDK for .NET: UI Design and MVVM. Wolf Kaiser, Charlie Macleod. Important Customization Patterns for the Pro SDK. MVVM Hooking Pro Commands MVVM – Lists & Collections Popups Layer and Custom popups. MVVM Pattern in Add-ins.
E N D
ArcGIS Pro SDK for .NET:UI Design and MVVM Wolf Kaiser, Charlie Macleod
Important Customization Patterns for the Pro SDK • MVVM • Hooking Pro Commands • MVVM – Lists & Collections • Popups • Layer and Custom popups
MVVM Pattern in Add-ins • MVVM and variants are de-facto pattern for WPF UI implementations • Many Frameworks available • Home grown or “hand rolled” • Commercial (free, purchased) • Pro MVVM is built on top of ActiPro (http://www.actiprosoftware.com/products/controls/wpf ) • The Basic Pattern is: • ViewModel declared in DAML and implemented in code • View referenced in DAML and implemented as WPF UserControl • Model is optional • Note: To customize the Pro UI, you must use its MVVM Framework. Substitutes are not allowed.
MVVM Pattern in Add-ins • Model-View-ViewModel (MVVM) Pattern used for many of the Framework elements • Dockpane • Pane • Custom Control • Embeddable Control • Property Page
Hooking Commands • Get any Pro control’s ICommand and use it in your add-in using Framework’s “GetPlugInWrapper” method. • Following example shows how a Pro control’s command can be added to your add-in button click method. (or anywhere else in your add-in). // ArcGIS Pro's Create button control DAML ID. varcommandId = DAML.Button.esri_mapping_createBookmark; // get the ICommand interface from the ArcGIS Pro Button // using command's plug-in wrapper // (note ArcGIS.Desktop.Core.ProApp can also be used) variCommand = FrameworkApplication.GetPlugInWrapper(commandId) asICommand; if (iCommand != null) { // Let ArcGIS Pro do the work for us if (iCommand.CanExecute(null)) iCommand.Execute(null); }
Hooking Commands • Adding a button to the Dockpane to run the ‘Close ArcGIS Pro’ Command • Adding a button to the Dockpane with our ‘custom’ Zoom in behavior • RelayCommand is an implementation of ICommand which lets you specify your own implementation of Execute and CanExecute
MVVM – Dockpane • Singleton • Has no context association with the ribbon and no active tool • Once created only hidden, never destroyed • View Model derives from the DockPane Contract • View is Custom User Control associated with DockPane declaratively • (Use of Model is optional and completely up to developer) <dockPanes> <dockPaneid="custom_TOCDockPane"caption="My Contents""className="DockPaneViewModel" dock="group“ condition="esri_core_MapPane""dockWith="esri_core_ProjectDockPane"> <contentclassName="DockPaneView""/> </dockPane> </dockPanes>
Multi-threading considerations • ArcGIS Pro Framework’s managed threading model: • Framework provides QueuedTask to guarantee that UI actions happen in a sensible order without corruption • Updating UI collections from a worker thread • Locking is required when sharing objects across threads • Recommended pattern for updating collections from a worker thread • Found in .NetBindingOperations helper class:BindingOperations.EnableCollectionSynchronization
Matching ArcGIS Pro Look & Feel • Check “ProGuide ArcGIS Pro Styles” for available styles, fonts, etc. • Example buttons:
Popups • Layer Popups– stored with the layer definition • “Explore” tool identify • Can be shared • Custom Popups – implemented in code and uses HTML5, Javascript, etc. • Eg Infographics tool • Not persisted.
Layer Popup Anatomy • Title + • array of “Media Infos”: Text Media Info Table Media Info (default) Chart Media Info - Line, Column, Bar, or Pie Image Media Info Attachments Media Info
Layer Popup - CIMPopupInfo • LayerDefinition.PopupInfo property namespaceArcGIS.Core.CIM { publicclassCIMPopupInfo : CIMObject { publicstring Title { get; set; } publicCIMMediaInfo[] MediaInfos { get; set; } //One of each only! QueuedTask.Run(() => { varlayerDef = layer.GetDefinition(); varpopupInfo = new CIMPopupInfo(); //TODO – create layer popup definition layerDef.PopupInfo = popupInfo; layer.SetDefinition(layerDef); });
Layer Popup • To invoke in code: publicclassMapView { publicvoidShowPopup(IReadOnlyDictionary<MapMember, List<long>> features); publicvoidShowPopup(MapMembermapMember, longfeatureID);
Custom Popups • Custom Popups – implemented in code and uses HTML5, Javascript, etc. • Not persisted in layer definition
Custom Popup Anatomy • Title • HTML Content • Can be URI • Commands
Custom Popup • Implement a PopupContent • Uses HTML or a URI (PopupContent.HtmlURI) • Is not persisted with a layer (or project) • No default content provided publicclassPopupContent : PropertyChangedBase { publicPopupContent(); publicPopupContent(stringhtmlContent, string title); publicPopupContent(UrihtmlURI, string title); publicPopupContent(MapMembermapMember, long id); publicstring Category { get; set; } publicstringHtmlContent { get; set; } publicUriHtmlURI { get; set; } publiclong ID { get; set; } publicboolIsDynamicContent { get; set; } publicMapMemberMapMember { get; set; } publicstring Title { get; set; } protectedinternalvirtualTask<string> OnCreateHtmlContent(); }
Custom Popup • To invoke in code: publicclassMapView { publicvoidShowCustomPopup(IEnumerable<PopupContent> popupContent); publicvoidShowCustomPopup(IEnumerable<PopupContent> popupContent, IEnumerable<PopupCommand> commands, boolincludeDefaultCommands);
Custom Popup • Basic implementation: • Assign MapMember and ID • Provide Content var popup = newPopupContent() { MapMember = layer, ID = oid, Title = "Custom Popup", HtmlContent = string.Format( "<head><body><p>{0}: Objectid{1}</p></body></html>",layer.Name, oid) }; MapView.Active.ShowCustomPopup(newList<PopupContent>() {popup});
Custom Popup • Dynamic Content: • Defer HTML content creation until the popup is shown • Derive custom class from PopupContent • Set IsDymanicContent = true • Implement OnCreateHtmlContent() • Useful if HTML content is complicated and/or there are many features selected (to “popup”) internalclassMyPopupContent : PopupContent { publicMyPopupContent() { IsDynamicContent = true; } protectedoverrideTask<string> OnCreateHtmlContent() { //TODO – must implement to create HTML “on demand” } }
Custom Popup – Custom Commands • Custom commands can be added to the command bar • Use PopupCommand. Provide an Execute method and (optionally) a CanExecuteMethod. • Use overload of MapView.ShowCustomPopup publicsealedclassPopupCommand : PropertyChangedBase { publicPopupCommand( Action<PopupContent> execute, Func<PopupContent, bool> canExecute, string tooltip, ImageSource image); } varpopupCMD = newPopupCommand((content) => {...}, (content) => content != null, "Show statistics", newBitmapImage(…)); var commands = newList<PopupCommand>(); commands.Add(popupCMD); MapView.Active.ShowCustomPopup(popupContent, commands, true);
Layer Popup Recap • Stored within the layer definition • Can be shared • LayerDefinition.PopupInfo • Consists of a Title and one or more Media Infos • Stored with the layer • Exporting the layer also exports the layer popup definition • Used by Explore Tool for Identify • Can be invoked via MapView.ShowPopup in the API
Custom Popup Recap • Custom Popups “live” in code • Implement a PopupContent • Must provide HTML Content or a URI • Use custom class derived from PopupContent for on-demand HTML Content • IsDynamicContent = true, must implement OnCreateHtmlContent • Add custom commands to command bar via PopupCommand and overload of MapView.ShowCustomPopup
Popups - Samples, Resources • https://github.com/Esri/arcgis-pro-sdk-community-samples • MapExploration • CustomPopup • MapToolWithCustomPopup • LayerPopups • API Reference: https://pro.arcgis.com/en/pro-app/sdk/api-reference/ • MapView.ShowPopup • MapView.ShowCustomPopup • LayerDefinition.PopupInfo • CIMPopupInfo • PopupContent
ArcGIS Pro SDK Resources • ArcGIS Pro SDK: Conceptual documentation, Code Snippets, Tutorials • https://github.com/Esri/arcgis-pro-sdk/wiki • ArcGIS Pro SDK Community Samples • https://github.com/Esri/arcgis-pro-sdk-community-samples • ArcGIS Pro SDK API Reference Guide • http://pro.arcgis.com/en/pro-app/sdk/api-reference
Please take our Survey Your feedback allows us to help maintain high standards and to help presenters Find your event in the Esri Events App Find the session you want to review Scroll down to the bottom of the session Answer survey questions and submit