Runtime Extensibility Framework

For Runtime .NET 100.12

Updated: 2021-10-02

The Runtime Extensibility Framework is a simple, open-source component that enables development of extensible, configurable, MVVM applications using the ArcGIS Runtime .NET SDK. Emphasis is placed on the following concepts:

RTReader, available for download, provides not only a ready-to-use application, but also an example of configuring and supporting the Extensibility Framework. This documentation will draw primarily upon it for examples.

Supporting the Extensibility Framework

In order to support the Extensibility Framework, a class in the application (typically the MainWindow model class) must implement the IMainWindow interface:

When the application launches, the main window initializes the Extensibility Framework by initializing the MapApplication object as follows:


MapApplication.Init(pMainWindow);

where pMainWindow is an instance of a class that implements IMainWindow. If the argument is null, MapApplication checks the application main window to see if it implements IMainWindow.

The MapApplication class also exposes the following members:

The MainLayoutModel is the master data context for the UI of the main window. It exposes the following members for binding:

The following method is also exposed:

The AppViewExt class is the default view extension; it provides an entry point to the map and manages tool registration and activation. It exposes the following members:

Three subfolders are expected to exist under the application executable, or else to be created and populated from corresponding subfolders under the folder defined by the UpdateLocation property:

Note that view and extension assemblies must have unique names. A view assembly cannot have the same name as an extension assembly.

The main layout in a view library is a UserControl which is declared in the configuration file (see below). Controls in the layout bind their data contexts to the DataContexts[KEY] property, where the key is a model extension provided by an extension class library. Here is an example of a typical tool button:

<RadioButton
   DataContext="{Binding DataContexts[QueryAddin.QueryTools]}"
   Command="{Binding IdentifyCommand}"
   ToolTip="Identify"
   Style="{StaticResource LayoutToolStyle}"
   IsChecked="{Binding IdentifyToolChecked}">
   <Image
      Source="Images/Identify.png"
      Style="{StaticResource LayoutIconStyle}"/>
</RadioButton>
Also, a ContentPresenter control binds its Content property to the MapViewContainerContent property, which is an instance of the MapView control. Multiple MapViews are currently not supported.

<ContentPresenter
   Grid.Column="1"
   Content="{Binding MapViewContainerContent}" />
The following is a list of interfaces to be implemented by the developer:

Various helper classes also exist for the benefit of the developer:

The Configuration File

The configuration file is named after the Configuration property (plus an .xml extension). [See the configuration file for RTReader for an example.] There are two main sections in the configuration file: "MainLayout" and "Extensions".

The "MainLayout" section contains the application title, the name of view assembly containing the main UI, and the name of the main UI class in the view assembly. [All UIs defining the main application and any child windows are expected to be subclasses of UserControl.] In addition, nonmodal child dialogs may be defined as instances of the ChildWindow or ChildItem class. ChildItems are typically panes in a multipane control such as a TabControl.

Here is an example MainLayout configuration:

   <MainLayout>
      <Title>DemoApp (TabletReader)</Title>
      <ViewAssembly>TabletViews</ViewAssembly>
      <MainLayoutName>MainLayout</MainLayoutName>
      <NonModalChild>ChildItem</NonModalChild>
      <ShowChildItemIcon>True</ShowChildItemIcon>
      <ShowChildItemTitle>False</ShowChildItemTitle>
   </MainLayout>
The "Extensions" section contains the declaration and configuration for each extension to be used in the application. Each "Extension" entry can have the following (optional) sections: Model extensions and view extensions may optionally implement the IConfigurable interface. In that case, a "ConfigData" section in the XML configuration provides a string which may be parsed appropriately by the extension upon loading.

Core Extensions

In addition to the main Extensibility component, code is also provided for several core extensions. Binaries are only provided for those extensions that are used in RTReader (NavAddin, QueryAddin, and LayoutAddin). It is up to the developer to compile the other extensions.

NavAddin

Provides support for map navigation, mobile map packages, ArcGIS map services, table of contents, map copy/export, and GPS location display.

The following commands are exposed to the UI:

Data Context KeyCommand
NavAddin.NavCommandsOpenMapCommand
NavAddin.NavCommandsExportMapCommand
NavAddin.NavCommandsCopyMapCommand
NavAddin.NavCommandsUserSettingsCommand
NavAddin.NavCommandsZoomInFixedCommand
NavAddin.NavCommandsZoomOutFixedCommand
NavAddin.NavCommandsZoomFullCommand
NavAddin.NavCommandsZoomPrevCommand
NavAddin.NavCommandsZoomNextCommand
NavAddin.NavCommandsGPSCommand
NavAddin.NavCommandsShowTOCCommand
NavAddin.NavCommandsHideTOCCommand
NavAddin.NavCommandsToggleCoordinatesCommand
NavAddin.NavCommandsSetUnitsCommand
NavAddin.NavCommandsExitCommand
NavAddin.NavModelExtScaleEnteredCommand
NavAddin.NavToolsZoomInCommand
NavAddin.NavToolsZoomOutCommand
NavAddin.NavToolsPanCommand

The following bindable properties are also exposed:

Data Context KeyPropertyType
NavAddin.MapModelExtTOCObservableCollection<TocDataItem>
NavAddin.MapModelExtStatusTextstring
NavAddin.MapModelExtCoordinateVisibilityVisibility
NavAddin.MapModelExtCoordinateTextstring
NavAddin.MapModelExtProgressVisibilityVisibility
NavAddin.NavCommandsOpenMapVisibilityVisibility
NavAddin.NavCommandsGPSVisibilityVisibility
NavAddin.NavModelExtMapReadybool
NavAddin.NavModelExtScaleItemsSourceObservableCollection<string>
NavAddin.NavModelExtScaleSelectedIndexint
NavAddin.NavModelExtScaleVisibilityVisibility
NavAddin.NavModelExtIsScaleVisiblebool
NavAddin.NavModelExtScaleTextstring
NavAddin.NavToolsZoomInToolCheckedbool
NavAddin.NavToolsZoomInToolCheckedbool
NavAddin.NavToolsPanToolCheckedbool

The following views are expected to exist in the referenced view library:

The "ConfigData" section for the MapModelExt model extension can have the following (optional) entries:

Here are some example entries:

   <Map Type="SimpleTestMap" />

   <Map Type="WebMap" Url="https://www.arcgis.com/home/item.html?id=388d367794ee43669606c04ca93eb8db" />

   <Map Type="BasicMap" Background="#FFF0F0F0" MaxScale="10" Extent="-9816800, 5125500, -9809200, 5130500">
      <TileCacheLayer DisplayName="Splash Screen" Path="C:\apps\DemoApp\Packages\SplashScreen.tpkx" MaxScale="30000" />
      <TileCacheLayer DisplayName="Naperville Imagery" Path="C:\apps\DemoApp\Data\naperville_imagery.tpkx" IsVisible="False" />
      <MobileMapPackageLayer DisplayName="Naperville Water" Path="C:\apps\DemoApp\Data\OfflineMapbook_v11.mmpk" MapIndex="1" IsExpanded="False" />
   </Map>
   <EnableTOC>True</EnableTOC>
   <ChildWindowTOC>True</ChildWindowTOC>
   <ShowTOC>False</ShowTOC>

QueryAddin

Provides support for Identify, Find, Go to XY, Measure, Highlight/Erase, and Text tools.

The following commands are exposed to the UI:

Data Context KeyCommand
QueryAddin.QueryCommandsFindCommand
QueryAddin.QueryCommandsGoToXYCommand
QueryAddin.QueryToolsIdentifyCommand
QueryAddin.QueryToolsMeasureCommand
QueryAddin.QueryToolsHighlighterCommand
QueryAddin.QueryToolsHighlighterMenuCommand
QueryAddin.QueryToolsEraserCommand
QueryAddin.QueryToolsEraserMenuCommand
QueryAddin.QueryToolsTextCommand

The following bindable properties are also exposed:

Data Context KeyPropertyType
QueryAddin.QueryToolsIdentifyToolCheckedbool
QueryAddin.QueryToolsMeasureToolCheckedbool
QueryAddin.QueryToolsHighlighterIconImage
QueryAddin.QueryToolsHighlighterToolCheckedbool
QueryAddin.QueryToolsHighlighterTextString
QueryAddin.QueryToolsEraserIconImage
QueryAddin.QueryToolsEraserToolCheckedbool
QueryAddin.QueryToolsEraserTextString
QueryAddin.QueryToolsTextToolCheckedbool

The following views are expected to exist in the referenced view library:

The "ConfigData" section for the QueryModelExt model extension can have the following (optional) entries:

Here are some example entries:

   <Identify ResultCollection="Tree" QueryRelated="True" />
   <AttachmentDialogModel Assembly="EditAddin" ClassName="EditAttachmentDialogModel" />

LayoutAddin

Provides support for map layouts that can be printed or exported to PDF. [PDF export assumes that the "Microsoft Print to PDF" driver is available.]

The following command is exposed to the UI:

Data Context KeyCommand
LayoutAddin.LayoutModelExtOpenLayoutCommand

The following bindable property is also exposed:

Data Context KeyPropertyType
LayoutAddin.LayoutModelExtOpenLayoutVisibilityVisibility

The following views are expected to exist in the referenced view library:

The "ConfigData" section for the LayoutModelExt model extension can have a "Layouts" entry containing one or more "Layout" entries. Each "Layout" entry must specify values for "Name", "DisplayName", "PageWidth", and "PageHeight" (using 96 dpi). A Layout may have optional "Property" entries to populate text blocks:

Here is an example XAML mark-up for a layout:

<UserControl x:Class="LayoutTest.AdHocLetterPortrait"
             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"
             mc:Ignorable="d"
             d:DesignHeight="1056" d:DesignWidth="816">
   <UserControl.Resources>
      <TextBlock x:Key="Title" Text="Ad Hoc Letter Portrait" />
      <Size x:Key="PageSize" Height="1056" Width="816" />
   </UserControl.Resources>
   <Canvas Height="1056" Width="816" Background="White">
      <Border Canvas.Left="48" Canvas.Bottom="48" Width="720" Height="960" BorderBrush="Black" BorderThickness="3">
         <Grid>
            <Grid.RowDefinitions>
               <RowDefinition />
               <RowDefinition Height="48" />
            </Grid.RowDefinitions>
            <Border Grid.Row="0" Margin="12, 12, 12, 0" BorderBrush="Blue" BorderThickness="3">
               <ContentPresenter Content="{Binding MapViewContainerContent}" />
            </Border>
            <Canvas Grid.Row="1">
               <TextBlock Canvas.Bottom="12" Canvas.Left="12" FontSize="24" Text="{Binding LayoutProperties[Title], FallbackValue=Title}" />
               <TextBlock Canvas.Top="6" Canvas.Left="440" FontSize="10" Text="Scale:" />
               <TextBlock Canvas.Top="6" Canvas.Left="480" FontSize="10" Text="{Binding LayoutProperties[Scale], FallbackValue=N/A}" />
               <TextBlock Canvas.Top="24" Canvas.Left="440" FontSize="10" Text="Date:" />
               <TextBlock Canvas.Top="24" Canvas.Left="480" FontSize="10" Text="{Binding LayoutProperties[Date], FallbackValue=N/A}" />
            </Canvas>
         </Grid>
      </Border>
   </Canvas>
</UserControl>
And here is an example configuration for it:

    <Layout Name="AdHocLetterPortrait" DisplayName="Ad Hoc Letter Portrait" PageWidth="816" PageHeight="1056">
       <Properties>
          <Property Name="Title" Type="Input" Label="Map Title" />
          <Property Name="Scale" Type="Scale" PageUnit="Inch" DistanceUnit="Feet"/>
          <Property Name="Date" Type="Date" FormatString="MM-dd-yyyy" />
       </Properties>
    </Layout>

EditAddin

Provides support for online editing or offline editing via the Sync Framework [Runtime Basic licensing may be required].

The following commands are exposed to the UI:

Data Context KeyCommand
EditAddin.EditModelExtDeleteGDBCommand
EditAddin.EditModelExtSynchronizeCommand

The following bindable property is also exposed:

Data Context KeyPropertyType
EditAddin.EditModelExtSynchronizeVisibilityVisibility

The following views are expected to exist in the referenced view library:

In order to work with QueryAddin, the "AttachmentDialogModel" entry should be set as follows:

   <AttachmentDialogModel Assembly="EditAddin" ClassName="EditAttachmentDialogModel" />
The "ConfigData" section for the EditModelExt model extension can have the following optional entry:

The "ConfigData" section for the EditViewExt view extension can have the following entries:

Here is an example configuration:

   <RemoteFeatureService Url="https://services.arcgis.com/nnn/arcgis/rest/services/Naperville_Markup/FeatureServer" />
   <LocalGeodatabase Path="C:\apps\DemoApp\Data\EditDemo.geodatabase" />
   <EditLayers GroupLayerName="Markups" Visible="True">
      <EditLayer Name="Map Change Request" Visible="True" ShowLabels="False" />
   </EditLayers>
   <AOI XMin="-88.17" YMin="41.77" XMax="-88.13" YMax="41.80" />
Here is an example of a Portal service:

   <RemoteFeatureService Url="https://gis.myserver.com/arcgis/rest/services/TestService/FeatureServer" />
   <PortalAuth Url="https://gis.myserver.com/portal/sharing/rest" AutoUserName="True"/>
It is up to the developer to create the code to perform the actual edits, typically in an exension. A feature table may be accessed from EditAddin as follows:
   ArcGISFeatureTable fTab = EditModelExt.Current.GetFeatureTable(sTableName);

AppUpdateAddin

Provides support for application updates, Runtime updates, local file updates, and local dataset updates. Multiple dataset/Runtime update locations are supported. The extension makes the following assumptions:

The following command is exposed to the UI:

Data Context KeyCommand
AppUpdateAddin.UpdateModelExtSetLocationCommand

The following bindable property is also exposed:

Data Context KeyPropertyType
EditAddin.EditModelExtLocationVisibilityVisibility

The following view is expected to exist in the referenced view library:

The extension should be the first in the "Extensions" section of the config file. The "ConfigData" section for the UpdateModelExt model extension is optional. The following entries may or may not be present:

Here is a sample configuration:

   <SetUpdateFolder>True</SetUpdateFolder>
   <Deletions>
      <Delete Path="C:\apps\DemoApp\Temp" />
   </Deletions>
   <FileUpdates>
      <File Source="Packages\SplashScreen.tpkx" Destination="C:\apps\DemoApp\Packages" />
   </FileUpdates>
   <DatasetUpdates>
      <Dataset Name="naperville_imagery.tpkx" Destination="C:\apps\DemoApp\Data" />
      <Dataset Name="OfflineMapbook_v11.mmpk" Destination="C:\apps\DemoApp\Data" />
   </DatasetUpdates>

Configuration Examples

Creating an Extension

More to come (hopefully)!


Return to ArcGIS Runtime page