ProConcepts Presentations - Esri/arcgis-pro-sdk GitHub Wiki
The Presentations functionality in ArcGIS Pro is delivered through the ArcGIS.Desktop.Presentations namespace in the ArcGIS.Desktop.Layouts assembly. This assembly provides classes and members that support managing presentations, presentation pages and working with the presentation views. This includes creating new presentations and pages, modifying existing presentations, and presentation view control and navigation.
- ArcGIS.Desktop.Presentations namespace in the ArcGIS.Desktop.Layouts.dll
Language: C#
Subject: Presentations
Contributor: ArcGIS Pro SDK Team <[email protected]>
Organization: Esri, http://www.esri.com
Date: 04/25/2025
ArcGIS Pro: 3.5
Visual Studio: 2022
- Presentation class
- Presentation View class
- Presentation page
- Elements in presentation
- Presentation events
- Export a presentation
- A complete, working example
The Presentation class provides access to basic presentation properties, presentation pages, and export methods. Presentations are stored within projects as presentation items (visible in the Catalog pane) and a project can contain many presentations. Existing presentation appear in the Catalog pane as individual project items, or as open (presentation) views. There can be one view open for a single presentation.
There are a two ways to reference an existing presentation in a project: First, reference a presentation associated with an active presentation view, assuming there is one open and active in the application. The presentation is accessible off the PresentationView's Presentation property (eg PresentationView.Active.Presentation
). If there is no active presentation view then "PresentationView.Active" will be null.
//Reference a presentation associated with an active presentation view
PresentationView activePresentation View = PresentationView.Active;
if (activePresentationView != null)
{
Presentation presentation= activePresentationView.Presentation;
}
Second, presentation can be accessed via their associated PresentationProjectItem, located in the Catalog pane. Use PresentationProjectItem.GetPresentation to return the underlying Presentation. To activate the presentation (i.e. open a presentation view), call ProApp.Panes.CreatePresentation PaneAsync(presentation);
. This is also covered in the Activate a Presentation View sub-section.
//Reference a presentation associated with a presentation project item
PresentationProjectItem presentationItem = Project.Current.GetItems<PresentationProjectItem>()
.FirstOrDefault(item => item.Name.Equals("Some Presentation Name"));
if (presentationItem!= null){
//Get the presentation associated with the presentationItem
Presentation presentation= await QueuedTask.Run(() => presentationItem.GetPresentation());
//Create the new pane - must be called on UI
IPresentationPane InewPresentationPane = await ProApp.Panes.CreatePresentationPaneAsync(presentation);
}
Presentations are created programmatically via the various PresentationFactory.Instance.CreatePresentation method overloads. When a presentation is created a presentation project item is added to the Contents pane but it is not automatically opened in a new presentation view. There are two overloads:
QueuedTask.Run(() =>
{
//Create a new presentation without parameters
var newPresentation = PresentationFactory.Instance.CreatePresentation ();
...
// Create a presentation specifying the name of the new presentation
var newPresentation = PresentationFactory.Instance.CreatePresentation("New Presentation");
...
});
Presentation views are the primary interface used to display, navigate, select, and edit presentation pages. The presentation being visualized in the view is accessed via the view's Presentation property (e.g. PresentationView.Active.Presentation). The page that is being displayed in a presentation view is accessed through ActivePage property. Note that:
- A presentation can only have one view in ArcGIS Pro.
- A presentation view may be open but may not be active.
- The active view is not necessarily a presentation view.
Assuming a presentation view is open, but not active, iterate through the pane collection on the FrameWorkApplication class, isolate the presentation pane of interest, and then active it. To open a new view (either for an existing presentation or a newly created presentation ) call FrameWorkApplication.Panes.CreatePresentationPaneAsync method. Pane activation must be called on the UI thread:
//Assume we want to open a view for a particular presentation or activate a view if one is already open
//A presentation project item is an item that appears in the Presentation folder in the Catalog pane.
PresentationProjectItem presentationItem = Project.Current.GetItems<PresentationProjectItem>()
.FirstOrDefault(item => item.Name.Equals("Some Presentation Name"));
//Reference a presentation associated with a presentation project item
if (presentationItem != null)
{
//Get the presentation associated with the presentationItem
Presentation presentation = await QueuedTask.Run(() => presentationItem.GetPresentation());
//Next check to see if a presentation view is already open that references the presentation
foreach (var pane in ProApp.Panes)
{
var prePane = pane as IPresentationPane;
if (prePane == null) //if not a presentation view, continue to the next pane
continue;
//if there is a match, activate the view
if (prePane.PresentationView.Presentation == presentation)
{
(prePane as Pane).Activate();
return;
}
}
//No pane found, activate a new one - must be called on UI
IPresentationPane InewPresentationPane = await ProApp.Panes.CreatePresentationPaneAsync(presentation);
}
When you add a new presentation to a project, the presentation view opens empty and the Contents pane does not contain any pages. To create a presentation page, either use PresentationPageFactory or various add page methods from an existing presentation. A presentation page cannot exist without an associated presentation in Pro. The page collection can be accessed via presentation's GetAllPages, and a single page can be retrieved via GetPage method using the page index. Examples below:
var presentation = PresentationView.Active.Presentation;
//Must be on QueuedTask
QueuedTask.Run(()=> {
// create a blank page using PresentationPageFactory
PresentationPageFactory.Instance.CreateBlankPage(presentation,-1); // index =-1 means add the page to the end of the page collection in a presentation
...
});
There are four types of presentation pages in Pro: Map, Blank, Image, or Video. A blank page is represented by PresesntationPage class, and there are three subclasses of PresesntationPage: ImagePresentationPage, VideoPresentationPage, MapPresentationPage. The page type can be retrieved using a page's PageType property.
A blank page has empty background. You can create a blank page with predefined template by using BlankPageTemplateType.
var presentation = PresentationView.Active.Presentation;
//Must be on QueuedTask
QueuedTask.Run(()=> {
// add a blank page with with title and paragraph body text element
presentation.AddBlankPage(BlankPageTemplateType.TitleAndParagraph, -1);
});
An Image presentation page uses a image as background. A imageURI must be specified when create a new image page. The image source can be updated via a image page's SetImageSource method.
var presentation = PresentationView.Active.Presentation;
//Must be on QueuedTask
QueuedTask.Run(()=> {
// add a new image page in current active presentation
var imagePage = presentation.AddImagePage("my image source", -1);
...
// change the image source
imagePage.SetImageSource("new image source");
});
Video pages use a video file as the page background. Supported video files supported are AVI, MP4, MPEG, and GIF. Similar to image page, a video source file needs to be specified when you create a new video presentation page and the video source is updated by SetVideoSource method. You can access the full duration of the source video by video page's FullLength property. The portion of the video you want to appear can be set by editing the start and end times of the video via SetStartTime and SetEndTime methods.
var presentation = PresentationView.Active.Presentation;
//Must be on QueuedTask
QueuedTask.Run(()=> {
// add a new video page in current active presentation
var videoPage = presentation.AddVideoPage("my video file", -1);
...
// change the image source
videoPage.SetVideoSource("new video source");
...
// change the start time of video to 3s
videoPage.SetStartTime(3.0);
// change the end time of video to 10s
videoPage.SetEndTime(10.0);
});
Map pages are made from any map or scene in the project. A map page can be created based on a map, a map view or a bookmark. The map source can be accessed via map page's MapURI property. This source can also be updated using SetMapSource method.
var presentation = PresentationView.Active.Presentation;
//Must be on QueuedTask
QueuedTask.Run(()=> {
// retrieve a map from the project based on the map name
MapProjectItem mpi = proj.GetItems<MapProjectItem>()
.FirstOrDefault(m => m.Name.Equals("Your Map Name", StringComparison.CurrentCultureIgnoreCase));
Map map = mpi.GetMap();
//create a map page using map's default extent
presentation.AddMapPage(map, -1);
//create a page using map's bookmark
Bookmark bookmark = map.GetBookmarks().FirstOrDefault(
b => b.Name == "Your bookmark"); // get the bookmark based on the bookmark's name
presentation.AddMapPage(bookmark , -1);
});
The map extent shown on a map page can be changed via SetCamera method.
Example: Change map page camera settings
//Must be on the QueuedTask
QueuedTask.Run(() =>
{
//Reference a map page
var mpage= activePresentationView.Presentation.GetPage(4) as MapPresentationPage;
//Set the map frame extent based on the new camera's X,Y, Scale and heading values
Camera cam = new Camera(329997.6648, 6248553.1457, 2403605.8968, 24);
mpage.SetCamera(cam);
});
Example: Zoom map page to extent of a single layer
//Must be on the QueuedTask
QueuedTask.Run(() =>
{
//Reference map page
var mpage= activePresentationView.Presentation.GetPage(4) as MapPresentationPage;
//Reference map and layer
MapProjectItem mp = Project.Current.FindItem(mp) as MapProjectItem;
Map map= mp.GetMap();
FeatureLayer lyr = map.FindLayers("GreatLakes").First() as FeatureLayer;
//Set the map frame extent to all features in the layer
mpage.SetCamera(lyr);
});
A map page being displayed on the current active presentation view can be "activated" to allow users to interact with the map to perform tasks such as manual navigation, selection ,etc. Once a map page is activated, the Presentation UI experience changes. Tools for map navigation and selection become available and users work with the map within the context of the presentation page. The rest of the presentation becomes unavailable (e.g. elements) until the map page is deactivated.
The following constraints apply for map page activation:
- A presentation view must be the active view in Pro
- Only one map page can be activated at any one time
- The map page must contain a valid map
- The map page must be visible and unlocked associated with the current active presentation view
- Activation must be executed on the UI thread*
The following constraints apply for map page deactivation:
- A presentation view must be the active view in Pro
- Deactivation must be executed on the UI thread* *This is the opposite of most API methods which normally require addins execute them on the MCT, Main CIM Thread, i.e. within a QueuedTask.Run
Example Activation:
//a presentation view must be active
if (PresentationView.Active == null)
return;
PresentationPage activePage = activePresentationView.ActivePage;
//check if the current page is a map page
//Note: we are on the UI thread!
if (activePage is MapPresentationPage)
{
activePresentationView.ActivateMapPageAsync();
}
//move to the QueuedTask to do something
QueuedTask.Run(() => {
TODO
});
Functionality for modifying elements is split between those methods accessed via the element itself versus those methods accessed on the presentation page. Presentation page property values are, for the most part, accessed via "Get" properties and "Set" method on the presentation page class itself.
The "basic" presentation page properties are:
- Visibility -
page.IsVisible, page.setIsVisible(true)
- Locked -
page.IsLocked, page.setIsLocked(true)
- HoldTime -
page.HoldTime, page.SetHoldTime(3.0)
- IsAutomaticAdvancement -
page.IsAutomaticAdvancement, page.SetAutomaticAdvancement(true)
With the Presentations SDK, it is possible to designate the appearance of a page via various settings such as BackgroundColor, Margin and Transition.
Example:
// create customized margin and color
CIMMargin pMargin = new CIMMargin() { Left = 0.2, Right = 0.3, Top = 0.15, Bottom = 0.25 };
CIMRGBColor pColor = new CIMRGBColor() { R = 255, G = 255, B = 0, Alpha = 50 };
//Reference a page and its transition
var page= activePresentationView.Presentation.GetPage(0);
CIMPresentationTransition transition = page.Transition;
// update the transition style
transition.TransitionType = PresentationTransitionType.Swipe;
transition.Duration = 2.0;
transition.SwipeDirection = SwipeDirection.Top;
//Must be on the QueuedTask
QueuedTask.Run(() =>
{
//Set the new margin, new background color and new transition effect
page.SetMargin(pMargin);
page.SetBackgroundColor(pColor);
page.SetTransition(transition);
});
To create presentation page content, the PresentationElementFactory is used. It provides a series of different macros for creating graphic element content (including point, line, and polygon, pictures, arrows and text elements) in a presentation. The elementContainer parameter on the various PresentationElementFactory methods identifies the presentation page or a group element associated with a presentation page within which a particular element will be created. The PresentationElementFactory.Instance provides the following methods for element creation:
- CreateArrowGraphicElement: Creates an arrow graphic based on the provided geometry and arrow info.
- CreatePictureGraphicElement: Creates a picture graphic element based on the input geometry and symbol.
- CreatePredefinedShapeGraphicElement: create predefined shapes using the PredefinedShape enum.
- CreateTextGraphicElement: Creates a text graphic based on the input geometry, symbol, text, etc.
Elements can also be created directly within an existing group element. You also have the ability to create new group elements as well via CreateGroupElement, either at the root level of the presentation page or within another group element. Passing a reference to the presentation page as the container will create the group at the root level of the page, whereas passing in a group element will create the group element at the root level of the referenced group element.
Example:
//Must be on QueuedTask
QueuedTask.Run(() =>
{
//create a picture element
var imgPath = @"https://www.esri.com/content/dam/esrisites/en-us/home/" +
"homepage-tile-podcast-business-resilience-climate-change.jpg";
//Build a geometry to place the picture
Coordinate2D ll = new Coordinate2D(3.5, 1);
Coordinate2D ur = new Coordinate2D(6, 5);
Envelope env = EnvelopeBuilderEx.CreateEnvelope(ll, ur);
//create a picture element on the page
var gElement = PresentationElementFactory.Instance.CreatePictureGraphicElement(page, env, imgPath);
//create a text element
//Set symbology, create and add element to a presentation page
CIMTextSymbol sym = SymbolFactory.Instance.ConstructTextSymbol(
ColorFactory.Instance.RedRGB, 15, "Arial", "Regular");
//use ElementInfo to set placement properties
var elemInfo = new ElementInfo()
{
Anchor = Anchor.CenterPoint,
Rotation = 45
};
string textString = "My text";
var textPos = new Coordinate2D(5, 3).ToMapPoint();
var tElement = PresentationElementFactory.Instance.CreateTextGraphicElement(page,
TextType.PointText, textPos, sym, textString, "telement", false, elemInfo);
//create a group element with elements created above
var elmList = new List<Element> { gElement, tElement };
GroupElement grp1 = PresentationElementFactory.Instance.CreateGroupElement(page, elmList, "My Group");
});
To find element content from a presentation, use either the FindElement or FindElements with the element names. Element names are unique within a presentation, so only the element, or element(s) in the case of FindElement_s_, with the matching name will be returned. The entire element hierarchy of the presentation is traversed to find the relevant element (or elements).
To retrieve elements, use either GetElements or GetFlattenedElements. GetElements() returns only the elements that are the immediate children of the container and element hierarchy is preserved. GetElementsAsFlattenedList(), on the other hand, recurses all nested groups to "flatten" the element hierarchy. It returns all elements from all nested groups as a single, flattened list. Hierarchy is not preserved. Note: just because an add-in uses GetElements or GetElementsAsFlattenedList over FindElement(s) doesnt mean that the retrieved list cannot be further refined. Addins can use LINQ on any of the returned element collections to further filter their content.
// reference current active page
PresentationPage activePage = PresentationView.Active.ActivePage;
//Must be on QueuedTask
QueuedTask.Run(() => {
// Find specific elements by name
var ge_rect = page.FindElement("Rectangle") as GraphicElement;
var elems = page.FindElements(new List<string>() { "Text, "Polygon" });
//Get elements retaining hierarchy
var top_level_elems = page.GetElements();
//Flatten hierarchy
var all_elems = page.GetFlattenedElements();
//Use LINQ with any of the collections
//Retrieve just those elements that are Visible
var some_elems = all_elems.Where(ge => ge.IsVisible).ToList();
});
Element selection is accomplished by calling either SelectElement or SelectElement_s_ with the element or collection of elements to be selected. Elements will be selected regardless of their level within the given presentation page. SelectElement(s) can be called either on the presentation page or the presentation view. The PresentationPage and PresentationView class have several methods for managing presentation element selection:
// reference current active presentation view
PresentationView activeView = PresentationView.Active
//Must be on QueuedTask
QueuedTask.Run(() => {
//Select/unselect some elements...
var elems = activeView.GetFlattenedElements();
//select any element not a group element
elems.SelectElements(elems.Where(e => !e.Name.StartsWith("Group")));
elems.UnSelectElements(elems.Where(e => !e.Name.StartsWith("Group")));
//Select/unselect all visible, graphic elements
var ge_elems = all_elems.Where(ge => ge.IsVisible).ToList();
activeView .SelectElements(ge_elems);
activeView.UnSelectElements(ge_elems);
//Select/unselect a specific element
var na = activeView.FindElement("My Text Element");
activeView.SelectElement(na);
activeView.UnSelectElement(na);
//Select everything
activePage.SelectElements(elems);
//enumerate the selected elements
foreach(var sel_elem in activeView.GetSelectedElements()) {
//TODO
});
The ArcGIS.Desktop.Presentations.Events namespace offers various selection and update events for presentation, presentation view and presentation pages. The namespaces provides events detection associated with context changes (add pages, remove pages, activation, deactivation, etc). For presentation changes (e.g. add/remove/move pages), refer to PresentationEvent and PresentationEventHint specifies the type of presentation event hits. For UI context changes associated with presentations use PresentationViewEvent and PresentationViewEventHint. For presentation page state changes (e.g. property or source changed), use PresentationPageEvent and PresentationPageEventHint.
Example
//Detect changes to the presentation modifications - listen for the relevant hint
ArcGIS.Desktop.Presentations.Events.PresentationEvent.Subscribe((args) => {
var presentation = args.Presentation; //The presentation that was changed
//Check what triggered the event and take appropriate action
switch (args.Hint) {
case PresentationEventHint.PropertyChanged:
//TODO handle presentation property changed
break;
case PresentationEventHint.PageAdded:
//TODO handle a new page added
break;
case PresentationEventHint.PageRemoved:
//TODO handle a page removed from the presentation
break;
case PresentationEventHint.PageSettingChanged:
//TODO handle page settings changed
break;
}
});
//For UI context changes associated with a presentation, subscribe to the PresentationView
//event - views activated/deactivated, views opened/closed
ArcGIS.Desktop.Presentations.Events.PresentationViewEvent.Subscribe((args) =>
//get the affected view and presentation
var view = args.PresentationView;
var presentation = args.PresentationView?.Presentation;
if (presentation == null) {
//FYI presentationview and/or presentation can be null...
//eg closed, deactivation
}
//Check what triggered the event and take appropriate action
switch (args.Hint) {
case PresentationViewEventHint.Activated:
//presentation view closed
break;
case PresentationViewEventHint.Opened:
//A PresentationView has been initialized
break;
case PresentationViewEventHint.Activated:
break;
case PresentationViewEventHint.Deactivated:
break;
case PresentationViewEventHint.Closing:
//Set args.Cancel = true to prevent closing
break;
case PresentationViewEventHint.ExtentChanged:
//presentation view extent has changed
break;
case PresentationViewEventHint.DrawingComplete:
break;
case PresentationViewEventHint.PauseDrawingChanged:
break;
}
});
A presentation can be exported to PDF, video and image series using Presentation.Export function. The function requires two arguments:
- ExportFormat to specify an export format.
- PresentationExportOptions to define export options such as page numbering.
Example
//On QueuedTask
//var presentation = ...;
//Create mp4 format with appropriate settings
MP4VideoFormat mp4Format = new MP4VideoFormat();
mp4Format.Width = 800;
mp4Format.Height = 600;
mp4Format.OutputFileName = @"my folder\presentation.mp4";
//Define Export Options
PresentationExportOptions options = new PresentationExportOptions {
PageRangeOption = ExportPageOptions.ExportByPageRange,
CustomPages = "1,2,8"
};
//export as mp4
presentation.Export(mp4Format, options);