WebGIS eTraining

WebGIS enables powerful geospatial web applications and services that securely share your organization’s rich geospatial data, and provides tools to deeply examine spatial data and create value added products, on demand.
Showing results for 
Search instead for 
Do you mean 

How to customize printing templates used by external printing service

by Technical Evangelist ‎05-12-2017 06:58 AM - edited ‎05-12-2017 07:00 AM (5,189 Views)

Table Of Contents


The external printing service uses XAML templates to generate print output. Server-sided printing is performed using a Snapshot Page that is opened in the server-side printing engine. After the snapshot page is fully loaded, the printing engine captures a bitmap. Bitmap is then applied to the template with other controls such as scale bar, legend and custom texts or images. See more on the internal mechanism here:


XAML Language and WPF

  • XAML, an Extensible Application Markup Language, is a XML-based markup design language developed by Microsoft and used by Windows Presentation Foundation (WPF) controls.
  • WPF is an interface for building modern, vector-oriented GUIs on Windows systems. WPF replaced the aging .NET Windows Forms. XAML shares principles of both XML and .NET.

WPF design advantages

  • WPF uses device independent pixels approach. Those are abstractly defined points that scale with DPI changes automatically. In effect, the controls and fonts behave like vectors. Correctly designed forms will look the same on different resolutions and DPIs, fonts or other content will not overflow its parent content.
  • Controls are positioned relatively to their parent containers and sibblings. You can simply compare this behavior to HTML/CSS design.
  • Control containers can define rotation and orientation of their content. Example:
      <RotateTransform Angle="-90"></RotateTransform>

WPF controls positioning

Take a look at the brief summary of positioning options for any elements placed in a parent container.




HorizontalAlignment="Stretch" (default)

Width="Auto" (default)

Element will stretch to full width of its parent.
Both attributes don’t need to be set explicitly.


Width="Auto" (default)

Element will snap to left border of its parent. Width will be set by its content.



Element will center horizontally to its parent. Width is exactly 100.



Illogical state, control cannot stretch and have an absolute width at the same time.

VerticalAlignment="Stretch" (default)

Height="Auto" (default)

Element will stretch to full height of its parent
Both attributes don’t need to be set explicitly.



Elemement will snap to top border of its parent and will have absolute height of 50.

VerticalAlignment="Stretch" (default)


Illogical state, control cannot stretch and have an absolute height at the same time.


You can also use margin and padding same way as in to HTML/CSS defitions.

  • Margin - defines outer edges of the element
  • Padding - defines inner space of the element


XML namespaces

Namespaces are used for clear definition (resolution) of classes and other types. Without a namespaces there would be many conflicts and each class would have to have unique name in the whole project scope, incl. external libraries. Every element therefore must use a namespace. If no namespace is explicitly specified, default will be used. Namespaces in XAML reference .NET assemblies. Examples:

Custom namespace definition:


Usage of namespace delivered with WPF:

<x:Window xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" />

Note: It is a common practice to define all namespaces in the root element of XML document, the namespace shortcuts are then accessible through whole document.

Properties and Attributes

Each XAML element comes with set of properties. Some of them are simple in-line properties but some of them can be structured.

Example of simple property:

<Grid Background="Gray" ... />

Example of structured property:

<Grid Background="Gray">
      <RowDefinition Height="59*" />
      <RowDefinition Height="88*" />

Some attributes are default, such as "Text" in the following example:

<Label Text="Hello" />

WPF Controls Examples


        <RowDefinition Height="50" />
        <RowDefinition Height="*" MinHeight="20" />
        <ColumnDefinition Width="*" />
        <ColumnDefinition Width="2*" />
        <ColumnDefinition Width="*" />
  • There will be two rows, one will be exactly 50 points high and the second will use the rest of the box model. If empty, it will be still 20pts high.
  • There will be three columns, where the first one will use 25% of the box, second 50% and third 25%.

Use inherited complex properties inside Grid.Row & Grid.Column to position the controls within a Grid. If those properties are not specified the content will be automatically placed to the first row / column. Example

<Image Grid.Row="2" Grid.Column="2" Stretch="Fill" Source="/images/pic1.png" />
<TextBlock Grid.Row="3" Grid.Column="2">Image Caption</TextBlock>


Used for positioning the elements in absolute coordinates related to canvas corners.

<Canvas Height="400" Width="400" >
    <Button Canvas.Top="10" Canvas.Left="10" Content="Button 1" />
    <Button Canvas.Top="40" Canvas.Left="20" Content="Button 2" />




Used for stacking elements one-after-another horizontally or vertically. Useful e.g. when too many Grid.RowDefinitions would be confusing.

<StackPanel Grid.Column="0" Orientation="Horizontal" Width="30">
   <Button Content="Button 1" Margin="2" />
   <Button Content="Button 2" Margin="2" />




Similar to StackPanel but wraps element to a new line or column if a corner is reached.

<WrapPanel Background="LightBlue" Width="200" Height="100">
    <Button Width="200">Button 1</Button>
    <Button>Button 2</Button>
    <Button>Button 3</Button>
    <Button>Button 4</Button>




For text descriptions, map coordinate display, disclaimers or additional information. Uses document “inlines” like <Bold>, <Italic>, etc.

<TextBlock>This is <Bold>bolded</Bold> text <LineBreak />
   and <Italic>Italic text</Italic> goes to a new line</TextBlock>



Inserting custom logos & other bitmaps onto printing output.

<Image Height="70" Width="606" Grid.Row="0" Grid.Column="0" Grid.ColumnSpan="2" 
   Margin="0.2cm,0.2cm,0,0" HorizontalAlignment="Left" VerticalAlignment="Top" Name="myImage" Stretch="Fill"
   Source="C:\Temp\Images\img.png" />


Creates and emphasizes actual content borders.

<Border BorderThickness="2" BorderBrush="Gray" 
   Grid.ColumnSpan="4" Grid.RowSpan="6" Grid.Column="1"
   HorizontalAlignment="Center" Width="717">   
     <Image ... />

Custom template controls

The printing engine assemblies come with several custom controls that are essential for the actual print. Those are:


Use this control to place a legend that was available to the user issuing print in Portal application. This control comes with property LegendImageSize, a complex property containing Size element with Height and Width values:

<LegendControl LegendImageSize="10,10" … >


Same as above but positioned vertically. VerticalLegendControl adds additional property LegendClipMessage that allows to define a message displayed in situation when legend does not fit the window and was clipped.


Basic control for placing a map. Has no specific properties.


Control for placing an additional scalebar. Usable properties are

  • Segments - number of black-white segments on the scale bar
  • Units - if used, automatically converts between "Metric" or "Miles"

NOTE: One scalebar is automatically rendered inside the map control but can be removed if custom snapshot page is developed.

Using custom controls in Visual Studio

Microsoft Visual Studio 2013 and later is recommended development environment when working with printing template files. It comes with WYSIWYG editor for XAML files, IntelliSense and validators. You can add the printing service custom controls to the Toolbox and simply drag and drop them onto the designer view.

  1. Launch Visual Studio and create a new WPF project.
  2. Open the XAML file in designer view and activate Toolbox.
  3. Create Printing Template Controls group and right click into an empty space.
  4. Add new controls using Choose Items...
  5. Locate PrintEngine.DLL assembly delivered with the printing service. It is usually located at:
    C:\Program Files\Common Files\Hexagon\Services\Supporting Services\PrintingService\bin
  6. Click Open.
  7. The custom controls available in this WPF library will be selected for you.
  8. Click OK.VS2.png
  9. Now you can drag and drop these controls to the designer view.

Basic Template Structure

The printing templates are specific when it comes to the default structure. Each XAML template should have this basic structure as a starting point. Note the custom namespaces definitions such as con, el and tm.

<tm:TemplateControl xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    TemplateDescription="Custom portrait template"
                    TemplateName="My Portrait Template"
    <!-- Grid is not mandatory but recommended as the main container -->
    <Grid Margin="1cm,1cm,1cm,1cm">

Templates Default Location

The template XAML files must be stored in
C:\Program Files\Common Files\Hexagon\Services\Supporting Services\PrintingService\App_Data\Resources\Templates

The printing service automatically reads those file and compiles them into resulting printout image. Should any problems occur while reading the XAML file you find related error message in the service's log file:

C:\Program Files\Common Files\Hexagon\Services\Supporting Services\PrintingService\App_Data\Resources\Logs

Template Parameters

There are two types of parametrs usable in printing templates. One of them are predefined system parameters while others are custom defined by the template developers. The system parameters have their values set during the print page generation or by user input. You can reference and display those values usually using Textblock elements. Binding mechanism is used to dynamically access the parameters during run time.

System Parameters - initialized by the Printing Engine

  • Map Extents: [xMin], [xMax], [yMin], [yMax]
  • CRS information: [crsId], [crsName]
  • Zoom level: ScaleSource

Example usage:

<TextBlock FontSize="8pt" Text="{Binding Path=Parameters.[yMax]}" ... />
<TextBlock FontSize="10pt" Text="{Binding Path=ScaleSource}" ... />

System Parameters - set by the user in the Common Options tab



Available parameters list:

  • TemplateDescription – description of the template, not visible anywhere else
  • TemplateName – custom template name
  • TemplateOrientation – Landscape or Portrait, or both
  • TemplatePageSizeNames – refine the actual page names (in case of non-standard template sizes
  • TemplateScales – refine list of available template scales

Custom Parameters - defined by template developer

Template developers can define their custom parameters that will appear in the Template Options tab. It is done through specifying custom attributes for user Textblock user control that can appear as:

  • Text input box
  • Checkbox
  • Date picker
  • Selection list
  • Multiline text area

Here's a list of the custom attributes available through tm namespace:

  • ParameterCategory - System or User - used to identify if this field bounds to a system predefined parameter or of it’s a custom defined paramater
  • ParameterDefault - Default value (e.g. preset text in the text box)
  • ParameterDescription - Label displayed in the printing dialog
  • ParameterType - Text by default; other options are Checkbox, Date, List and Textarea
  • ParameterValues - list of values for lists

Following example shows a parameters definition:


Sample Template

Please find attached below a sample template that should render as following.


‎04-05-2018 07:43 PM - edited ‎04-05-2018 07:49 PM

After editting an XAML Printing Template file, what is required in order for the new version of the file to be used the next time Webmap is accessed..  Sometimes restarting IIS is all that is needed but sometimes the changes don't show-ip.  I have also tried deleting any mapmngr processes.  Is there a cache somewhere that needs files deleted?  Thanks....

by Technical Evangelist
on ‎04-06-2018 12:00 AM

If I recall correctly, it should be enough to remove and re-add the Printing Service to the list of Data Sources in Portal...

on ‎04-08-2018 08:35 AM

That did the trick except once i got an error when i tried to reformat a date incorrectly and i ended up rebooting.  Thanks!

I have by portrait and landscape templates working well now except the portrait one shows the scalebar from the map display on the SDK webpage and the landscape one does not.  I also show an image of a north arrow with the user selected scale underneath.  I don't want the scale bar to display (see attached image) - Is there a way to turn it off?  It doesn't display on my Landscape view.  I am using this code to add the map view:



(portrait view - scale bar is displayed on pdf map)
<Border Grid.Row="1" Grid.Column="0" Margin="2" BorderThickness="1" BorderBrush="Black" Grid.ColumnSpan="3" > <el:MapControl x:Name="MapControl1" /> </Border>

(landscape view - no scale bar on pdf map)
<Border Grid.Row="1" Grid.Column="0" Grid.RowSpan="2" Margin="8" BorderThickness="1" BorderBrush="Black" Grid.ColumnSpan="1" >
<el:MapControl x:Name="MapControl1" />

Image Below:




by Technical Evangelist
on ‎04-09-2018 03:57 AM

Having scalebar visible on one but not on another template is a bit strange. There could be some decision mechanism which detects the MapControl container parametrs and decides if there's a place for scalebar or not. But I'm only guessing here.

Anyway, you can disable the scalebar by creating a custom snapshot page and removing the HTML element during the snapshot Page initialization by adding:

$GP.ready(function() {

to the SnapshotPage.js:



‎04-11-2018 06:28 AM - edited ‎04-11-2018 06:29 AM

Thanks - the snapshot-page_for_printing page refers to using the PhantomJS or Internet Explorer print engines.  I have to use GraphicMagick so that I can offer PDF printing.  Can the snapshot page be used with the GraphicicsMagic engine?  As an alternative, I tried turning of the scale bar before issueing the print request and it still displayed even though it was not displaying on my screen.