Skip to content

Create a custom page

Christopher Vazquez edited this page Jun 28, 2024 · 29 revisions

In some cases you might not want to customize the existing metadata editor pages. For example, if you would like to include information in item metadata that is specific to your organization's data management workflow, it might be best to keep all of that information on a separate page and leave the pages provided in the ArcGIS Pro metadata editor alone.

In this topic

Add a page that edits custom metadata elements

The following instructions outline how you would create a custom metadata editor page that begins mostly blank.

  1. Open the Visual Studio project created when you built your first metadata editor add-in.

  2. In the Solution Explorer window, open the Pages folder and double-click CustomPage.xaml page to open it.

  3. Expand the CustomPage.xaml entry in the Solution Explorer window, then double-click CustomPage.xaml.cs to open the file containing the C# code associated with the custom page as well.

    At the bottom of the list of declarations, lines are already present referencing the ArcGIS Pro metadata editor's namespaces:

using ArcGIS.Desktop.Metadata;
using ArcGIS.Desktop.Metadata.Editor.Pages;
  1. The custom page is already set up to use the correct namespace CustomMetadataEditor1.Pages, and to inherit from the EditorPage class in the ArcGIS Pro Metadata.Editor assembly by using the public partial class declaration of EditorPage.
namespace CustomMetadataEditor1.Pages
{
  internal class CustomPageLabel : ISidebarLabel
  {
    ...
  }

  /// <summary>
  /// Interaction logic for CustomPage.xaml
  /// </summary>
  public partial class CustomPage : EditorPage
  {
      ...
  }
}
  1. In the Solution Explorer window, open the Properties folder and double-click the Resources.resx file to open it.

  2. In the toolbar at the top of the Resource Designer, see that the resource view is set to Strings.

    All labels that appear on all pages in the metadata editor are already available as resources in this project. Various string resources are required for the custom page, and will be referenced from this string resources table. A string resource is needed to provide a name for the custom page that appears in the metadata editor's Contents pane. These strings should be short to minimize the default width needed for the Contents pane when it is used with the Metadata editor view.

  3. Set the value in the Access Modifier drop-down list to Public. A Microsoft Visual Studio warning appears. Click Yes to indicate you want to edit this file.

  4. Scroll to the bottom of the string resources table. In the last row of the table, marked with an asterisk (*), click in the Name column. Replace the default text "String1" with "CUSTOM_PAGE_NAME". Click in the Value column, and type the phrase "Process Tracking", then press Enter.

  5. A metadata editor page also needs a title that appears at the top of the Metadata editor view. This string can be longer and more descriptive. Repeat the process above to add another string resource named "CUSTOM_PAGE_TITLE" with the value "Internal Process Tracking Information". Save your changes.

  6. Add string resources for two controls that will be added to the custom page later to edit trackingPosition and trackingStatus metadata elements. Provide strings to label these controls with identifiers such as “CUSTOM_TRK_POSITION” and “CUSTOM_TRK_STATUS”. Use text for the labels such as "Tracking Position" and "Tracking Status", respectively.

  7. In the CustomPage.xaml.cs file, define the page’s SidebarLabel property; it will return the string for the page’s entry in the Metadata editor view’s Contents pane. This property will reference the CUSTOM_PAGE_NAME string resource that was just added to the project by specifying Properties.Resources.CUSTOM_PAGE_NAME, in place of the string that was previously provided, "Custom Page".

namespace CustomMetadataEditor1.Pages
{
  internal class CustomPageLabel : ISidebarLabel
  {
      string ISidebarLabel.SidebarLabel
      {
          get { return CustomPageLabel.SidebarLabel; }
      }

      public static string SidebarLabel
      {
          get { return Properties.Resources.CUSTOM_PAGE_NAME; }
      }
  }

  /// <summary>
  /// Interaction logic for CustomPage.xaml
  /// </summary>
  public partial class CustomPage : EditorPage
  {
    public CustomPage()
    {
      InitializeComponent();
    }
    public override string SidebarLabel
    {
      get { return CustomPageLabel.SidebarLabel; }
    }
  }
}
  1. Save your changes, and close the CustomPage.xaml.cs file.

  2. In the open CustomPage.xaml file, maximize the XAML pane associated with this page. This custom page has a root element that declares the control to be an EditorPage. Update the appropriate namespaces and event handlers as illustrated below.

    Any ArcGIS Pro namespaces must include their assembly. If a control provided by the WPF Toolkit is later added to the page, the appropriate namespace for that control must also be provided. All contents in this file are case-sensitive. When declaring the page’s class and its properties, make sure the namespace matches the assembly namespace and the class name matches the class name as declared in the CustomPage.xaml.cs file.

    Add a declaration to the list that allows you to access the new resource strings you added on the custom page, using the proper namespace for your solution: xmlns:r="clr-namespace:CustomMetadataEditor1.Properties". To the end of the declarations, add the following: Loaded="FillXml".

<p:EditorPage x:Class="CustomMetadataEditor1.Pages.CustomPage"
     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:CustomMetadataEditor1.Pages"
     xmlns:r="clr-namespace:CustomMetadataEditor1.Properties"
     xmlns:p="clr-namespace:ArcGIS.Desktop.Metadata.Editor.Pages;assembly=ArcGIS.Desktop.Metadata"
     xmlns:extensions="clr-namespace:ArcGIS.Desktop.Extensions;assembly=ArcGIS.Desktop.Extensions"
     mc:Ignorable="d"
     d:DesignHeight="450" d:DesignWidth="800"
     Loaded="FillXml">

</p:EditorPage>
  1. A page in the ArcGIS Pro metadata editor is fundamentally a UserControl. Controls added to a XAML page must bind to specific XML elements; those elements must exist in the metadata XML document for the page to work. An ArcGIS metadata editor page must have a resource that provides an XML fragment to which the controls can bind. The XML elements in the fragment will be added to the item's metadata if they don’t already exist.

    The way XAML forms typically work, if content isn’t provided when the page is used or if the content provided isn’t saved, the XML elements that were added by the XML fragment will remain saved in the document without any content. This is a problem for metadata documents, which have strict validation rules. The presence of an optional element can trigger validation rules that require additional information. Also, empty elements are considered errors when metadata is validated with an XML schema. A metadata XML document can’t include empty XML elements. Therefore, the ArcGIS Pro metadata editor always ensures that any empty XML elements are removed before the metadata is saved.

    The XmlDataProvider resource illustrated below provides the XML fragment that will be added to the item's metadata to support the controls that will be added to the page. This XmlDataProvider must be added to the existing UserControl.Resources section for the custom page, and it must have the unique key "XmlRecord". All metadata elements that are defined in this manner need to be in the same "XmlRecord" data provider. If you have additional data providers that define partial XML fragments, their keys must begin with "XmlRecord_". For example, this technique is used in some of the pages that are provided from the ArcGIS Pro metadata editor. A ResourceDictionary is available in the custom page by default. If you choose to use it, the XmlDataProvider must be provided within the ResourceDictionary, but outside of the MergedDictionaries as illustrated below. Alternatively, the ResourceDictionary can be removed, and the XmlDataProvider can be provided on its own.

<p:EditorPage ... >
  <UserControl.Resources>
    <ResourceDictionary>
      <ResourceDictionary.MergedDictionaries>
        <extensions:DesignOnlyResourceDictionary Source="pack://application:,,,/ArcGIS.Desktop.Framework;component\Themes\Default.xaml"/>
      </ResourceDictionary.MergedDictionaries>

      <XmlDataProvider x:Key="XmlRecord" XPath="/"
                       IsAsynchronous= "False"
                       IsInitialLoadEnabled= "True">
        <x:XData>
          <ANY xmlns="">
            <metadata>
              <custom>
                <myData>
                  <trackingPosition>0000</trackingPosition>
                  <trackingStatus>editing</trackingStatus>
                </myData>
              </custom>
            </metadata>
          </ANY>
        </x:XData>
      </XmlDataProvider>
    </ResourceDictionary>
  </UserControl.Resources>
</p:EditorPage>

In this example, the custom metadata elements trackingPosition and trackingStatus are added to a custom myData section in the item’s metadata and the elements include default values. Custom metadata elements are allowed in ArcGIS metadata. They must be added within a separate section of the ArcGIS metadata XML document inside the "custom" metadata element. Within this section, your content should be provided within a root element that is unique for your organization; in this example it is "myData". The XSLT stylesheet used to display metadata must be updated later to show any information the custom elements contain.

Learn how to customize the metadata display

  1. Add any additional required resources alongside the first XmlDataProvider. Each resource must have a unique Key. This example provides another XmlDataProvider with a set of values that will appear in a custom drop-down list. The values are specified as XML data with the unique Key OrgStatusCodes.
<p:EditorPage … >
  <UserControl.Resources>
    <ResourceDictionary>
      ...
      <XmlDataProvider x:Key="XmlRecord" XPath="/"
                       IsAsynchronous= "False"
                       IsInitialLoadEnabled= "True">
        ...
      </XmlDataProvider>
      <XmlDataProvider x:Key="OrgStatusCodes" XPath="/"
                       IsAsynchronous= "False"
                       IsInitialLoadEnabled= "True">
        <x:XData>
          <ANY xmlns="">
            <statuscodes>
              <status>editing</status>
              <status>complete</status>
              <status>reviewed</status>
              <status>published</status>
              <status>rejected</status>
            </statuscodes>
          </ANY>
        </x:XData>
      </XmlDataProvider>
    </ResourceDictionary>
  </UserControl.Resources>
</p:EditorPage>
  1. Controls on the page are positioned using a stack panel within a top-level grid that is placed on the page following its resources. Delete the existing contents of the Grid that are provided by default: Grid.RowDefinitions and DockPanel, and add a StackPanel in their place. A XAML page that has an entry in the metadata editor's table of contents should use the Grid style "EditorFrontPageStyle".
<p:EditorPage>
  <UserControl.Resources>
    ...
  </UserControl.Resources>
  <Grid Style="{DynamicResource EditorFrontPageStyle}">
    <StackPanel>
      ...
    </StackPanel>
  </Grid>
</p:EditorPage>
  1. The first control on the page is always the page title, which is the first child of the stack panel. The page title is displayed using a Label control with the style EditorPageTitle. The Label control’s Content attribute specifies its text; identify the CUSTOM_PAGE_TITLE string resource provided in step 7 by typing r:Resources.CUSTOM_PAGE_TITLE. When the namespaces were defined for this XAML page, xmlns:r was set appropriately to allow you to access the project’s properties.
<Grid Style="{DynamicResource EditorFrontPageStyle}">
  <StackPanel>
    <!-- page title -->
    <Label Style="{DynamicResource EditorPageTitle}"
            Content="{x:Static r:Resources.CUSTOM_PAGE_TITLE}"/>
    ...
  </StackPanel>
</Grid>
  1. On the XAML page, controls that allow you to manipulate the metadata content will be added to the stack panel below the Label that provides the page title.

    Because more than one control will be used to edit a set of metadata elements that begin with the same XPath, and those values should be placed in the same group in the item's metadata, these controls should be organized and positioned on the page within a list box. The ListBox control identifies the base XPath from which its controls will operate: /metadata/custom/myData. Because there are multiple controls in the group, add a stack panel inside the ListBox as illustrated below.

<Grid Style="{DynamicResource EditorFrontPageStyle}">
  <StackPanel>
    <!-- page title -->
    <Label Style="{DynamicResource EditorPageTitle}"
           Content="{x:Static r:Resources.CUSTOM_PAGE_TITLE}"/>

    <!-- custom metadata elements -->
    <ListBox Style="{DynamicResource EditorNoScrollListBoxStyle}"
             ItemsSource="{Binding XPath=/metadata/custom/myData}">
      <ListBox.ItemTemplate>
        <DataTemplate>
          <StackPanel>
          
          </StackPanel>
        </DataTemplate>
      </ListBox.ItemTemplate >
    </ListBox>
  </StackPanel>
</Grid>
  1. Add a control that edits the trackingPosition element. A Label must be provided to identify the metadata element, along with a TextBox control that allows you to edit its content. These controls are grouped together using a dock panel, which is placed within the list box’s stack panel.

    Set the Label control’s Content attribute to use the CUSTOM_TRK_POSITION string resource. Set the controls to use the same style as other controls in the editor.

    Complete the binding to the metadata XML document by specifying the remainder of the XPath for the metadata element associated with the TextBox control. Set the TextBox control’s XPath to trackingPosition. Any text provided with this control will be stored in the metadata XML document in the following location: /metadata/custom/myData/trackingPosition.

<StackPanel>
  <!-- page title -->
  <Label Style="{DynamicResource EditorPageTitle}"
         Content="{x:Static r:Resources.CUSTOM_PAGE_TITLE}"/>

  <!-- custom metadata elements -->
  <ListBox Style="{DynamicResource EditorNoScrollListBoxStyle}"
            ItemsSource="{Binding XPath=/metadata/custom/myData}">
    <ListBox.ItemTemplate>
      <DataTemplate>
        <StackPanel>
          
          <!-- tracking position -->
          <DockPanel LastChildFill="True"
                     HorizontalAlignment="Stretch">
            <Label DockPanel.Dock="Left"
                   Style="{DynamicResource EditorHLabelNoIdentStyle}"
                   Content="{x:Static r:Resources.CUSTOM_TRK_POSITION}"/>
            <TextBox Style="{DynamicResource EditorTextBoxStyle}"
                     Text="{Binding XPath=trackingPosition, Mode=TwoWay}"/>
          </DockPanel>

        </StackPanel>
      </DataTemplate>
    </ListBox.ItemTemplate >
  </ListBox>
</StackPanel>
  1. Following the controls for editing the trackingPosition element, add controls to the list box’s stack panel to edit the trackingStatus element. A Label must be provided to identify the metadata element, along with a ComboBox control to edit its content. These controls are grouped together using the same method described above.

    Set the Label control’s Content attribute to use the CUSTOM_TRK_STATUS string resource. Set the controls to use the same style as other controls in the editor.

    The values that will appear in the drop-down list were defined as a resource for this page in the XmlDataProvider with the Key OrgStatusCodes. To display these values in the list, set the ComboBox control’s ItemsSource property to use the resource with the OrgStatusCodes Key, and use its XPath property to select data from the status elements in that resource. The values in the XmlDataProvider's status elements will appear in the list.

    Meanwhile, the ComboBox.SelectedValue binding determines where the selected value will be stored in the item’s metadata. Its XPath property specifies the remainder of the XPath that was started by the ListBox; when set to trackingStatus, the value selected in the ComboBox will be stored in the metadata XML document in the following location: /metadata/custom/myData/trackingStatus. Both the trackingPosition and trackingStatus elements will reside within the same myData element.

<ListBox Style="{DynamicResource EditorNoScrollListBoxStyle}"
          ItemsSource="{Binding XPath=/metadata/custom/myData}">
  <ListBox.ItemTemplate>
    <DataTemplate>
      <StackPanel>
          
        <!-- tracking position -->
        <DockPanel LastChildFill="True"
                   HorizontalAlignment="Stretch">
          ...
        </DockPanel>

        <!-- tracking status -->
        <DockPanel LastChildFill="True"
                   HorizontalAlignment="Stretch">
          <Label DockPanel.Dock="Left"
                  Style="{DynamicResource EditorHLabelNoIdentStyle}"
                  Content="{x:Static r:Resources.CUSTOM_TRK_STATUS}"/>

          <ComboBox Loaded="PostProcessComboBoxValues" 
                    SelectionChanged="ComboBoxSyncSelectionChanged" 
                    Style="{DynamicResource EditorHComboBoxStyle}" 
                    IsEditable="False" 
                    ItemsSource="{Binding Source={StaticResource OrgStatusCodes}, XPath=//status}" 
                    DisplayMemberPath="." 
                    SelectedValuePath=".">

            <ComboBox.SelectedValue>
              <Binding XPath="trackingStatus" Mode="TwoWay"/>
            </ComboBox.SelectedValue>

          </ComboBox>
        </DockPanel>

      </StackPanel>
    </DataTemplate>
  </ListBox.ItemTemplate >
</ListBox>
  1. Open the Config.daml page. By default, as described in Build your first ArcGIS Pro metadata editor, the custom metadata editor will include all pages required to create metadata that complies with the ISO 19115/19139 metadata standards. All pages in the custom editor will be derived from the custom metadata editor add-in.

    An entry is already present in the custom metadata editor's configuration for the custom page. It is included at the bottom of the Overview section following the TODO comment:

<!-- TODO add your custom pages for Overview here -->
<page class="CustomMetadataEditor1.Pages.CustomPage">
  <validation>
  </validation>
</page>

As described in Use a different stylesheet to display metadata, update the viewerXSLT property to display the item's metadata as an XML document so you will be able to see the custom metadata elements added by your custom metadata editor page.

<metadataConfig ArcGISProfile="ISO19139" ValidatePages="True">
  <validationNamespaceURI></validationNamespaceURI>
  <validationSchemaURL></validationSchemaURL>
  <tranformStyle>ISO19139</tranformStyle>
  <viewerXslt>Metadata\Stylesheets\XML.XSL</viewerXslt>
  <editor>
  1. As described in Build your first ArcGIS Pro metadata editor, build the CustomMetadataEditor1 project. Make sure there are no errors that prevent the project from building successfully. An .esriAddinX file is created and automatically added to ArcGIS Pro.

    If you haven't selected the custom metadata editor's metadata style yet in ArcGIS Pro, start the application and click Settings on the Start Page. Click Options, and click the Metadata tab in the Options dialog box. Click the custom metadata style in the drop-down list, for example, CustomMetadataEditor1 Metadata Toolkit Editor, then click OK.

  2. Open a project, and open a Catalog view. Make sure the Details panel is open in the active Catalog view.

  3. Click Project in the Catalog view's Contents pane to see its metadata in the Details panel in the Catalog view.

  4. On the Catalog tab on the ribbon, in the Metadata group, click Edit. The Metadata view opens. All pages typically associated with the ISO 19139 metadata style are present in the editor; however, these pages are all derived from the ArcGIS Pro metadata toolkit.

  5. In the Overview section, click the Process Tracking page.

  6. Type a value into the Tracking Position text box.

  7. Click the Tracking Status drop-down list. Select a value in this list.

  8. On the Metadata tab on the ribbon, in the Manage Metadata group, click Save. Close the Metadata view.

  9. The Contents view will be active again. Click Project in the Contents pane to see the project's metadata. Scroll down to find the custom metadata elements that were entered.

If you examine the XML structure of the item’s metadata, you can see that the following custom content is now included in the document alongside the rest of the ArcGIS metadata content.

If you were to provide this custom page to someone else, it should be accompanied by a custom metadata stylesheet that is able to display the content that may be provided in the custom metadata elements. The metadata display that is used by this custom metadata style doesn't know how to display the custom values that have been added to the metadata.

Learn how to Customize the metadata display