-
Notifications
You must be signed in to change notification settings - Fork 120
ProConcepts Content and Items
This ProConcepts will go cover content in Pro, its usage, and relevant API functionality.
Language: C# and Visual Basic
Subject: Content
Contributor: ArcGIS Pro SDK Team <[email protected]>
Organization: Esri, http://www.esri.com
Date: 6/13/2017
ArcGIS Pro: 2.0
Visual Studio: 2015, 2017
In this topic
- Overview
- Project Content
- External Content
- ItemFactory and AddItem
- ItemFactory and Import
- Items and Factories
- Getting Item Content
- Catalog Context
In Pro, content is represented as Items (Item topic 9110). There are two categories of Items:
- Content that is stored in, or referenced by, the Project document. This content, is referred to as project content (or project "items")* and includes maps, layouts, styles, toolboxes, folders, etc.
- Content that is browsed by Pro and is external to the project. Content can be browsed from folders, portal and online, geodatabases, and toolboxes and includes text files, xml files, folders, database connection files, layer files, task files, mxds, sxds, etc. This content, is referred to as external content (or external "items").
*Content can also be included within Favorites at 2.0.
Project content, or project "items", lives within the project. At some point in time, project content was either added or imported into the project from an external source or was created (and saved) in a Pro session. Once in a project, content can packaged and shared (see Project Package)
In the API, project "items" all include the suffix ProjectItem
in their class name and derive from ArcGIS.Desktop.Core.Item
(by way of a couple of internal classes not relevant to the public API). Project item classes implement the interface IProjectItem
(topic 15851) which is the required parameter type for adding and removing content to and from Pro ( Project.Current.AddItem(IProjectItem item)
, topic 15947, and Project.Current.RemoveItem(IProjectItem item)
, topic 15951). Adding content to the project is discussed in detail in ItemFactory and AddItem.
The public API currently provides the following project items:
Class | Namespace | Assembly |
---|---|---|
FolderConnectionProjectItem | ArcGIS.Desktop.Catalog | ArcGIS.Desktop.Catalog.dll |
GDBProjectItem | ArcGIS.Desktop.Catalog | ArcGIS.Desktop.Catalog.dll |
GeoprocessingProjectItem | ArcGIS.Desktop.GeoProcessing | ArcGIS.Desktop.GeoProcessing.dll |
HistoryProjectItem | ArcGIS.Desktop.GeoProcessing | ArcGIS.Desktop.GeoProcessing.dll |
LayoutProjectItem | ArcGIS.Desktop.Layouts | ArcGIS.Desktop.Layouts.dll |
LocatorsConnectionProjectItem | ArcGIS.Desktop.Catalog | ArcGIS.Desktop.Catalog.dll |
MapProjectItem | ArcGIS.Desktop.Mapping | ArcGIS.Desktop.Mapping.dll |
ReviewerBatchJobProjectItem | ArcGIS.Desktop.DataReviewer | ArcGIS.Desktop.DataReviewer.dll |
ReviewerResultsProjectItem | ArcGIS.Desktop.DataReviewer | ArcGIS.Desktop.DataReviewer.dll |
StyleProjectItem | ArcGIS.Desktop.Mapping | ArcGIS.Desktop.Mapping.dll |
ServerConnectionProjectItem | ArcGIS.Desktop.Catalog | ArcGIS.Desktop.Catalog.dll |
TaskProjectItem | ArcGIS.Desktop.TaskAssistant | ArcGIS.Desktop.TaskAssistant.dll |
Any content that can be browsed (and can be indexed by Pro for browsing) is considered "external content". External content items derive from ArcGIS.Desktop.Core.Item
same as project content items. External content items represent the many different file types or folder types (images, text files, file geodatabase folder, style files, zip archives, etc.) that can exist online or on a physical disk drive whether it can be added to Pro or not. For example, when enumerating the contents of a folder, items are returned for all the content, not just the Pro specific content.
Note: The majority of the external content types derive from Item via "Desktop.Internal" classes (as do project items)*. This is an implementation detail not relevant to the public API. Simply treat them as "Items" in your code because that is what they are. The underlying "Desktop.Internal" classes provide Catalog the functionality it needs to show special icons, customize context menus, provide browsing support (for containers) and that sort of thing.
*Some items are instantiated as "ProjectItem" classes directly by ItemFactory.Instance.Create. These are covered in the next section.
Creating and adding content to a project is a three step process:
-
Create a content item using
ItemFactory.Instance.Create
using the path or url to the content (whether on disk or online). -
Test the returned content for
IProjectItem
* to see if it can be added to the project. -
If it implements IProjectItem, add the content to the project via
Project.Current.AddItem
. AddItem returns true if the item was successfully added.
Internally, the process of "adding" ensures the item is stored within the correct container (Maps for Maps, Layouts for Layouts, Toolboxes for Toolboxes, etc.) and is added to the internal project repository. Note: Project.Current.AddItem must be called within a QueuedTask lambda.
This example creates a layer file item and tests it to see if it can be added to the Project. (The test will fail and show the message box - layer files can only be added to maps (with LayerFactory) - not projects)
//test to see if a layer file can be added
string path = @"E:\Pro\USA\Us_States.lyrx";
Item item = ItemFactory.Instance.Create(path, ItemFactory.ItemType.PathItem);
if (item is IProjectItem)
QueuedTask.Run(() => Project.Current.AddItem((IProjectItem)item));
else
//A layer file can NOT be added to a project. It can only be added to a map
MessageBox.Show($"{item.Path} cannot be added to a project", "Content");
*If you already know that an item is an IProjectItem (e.g. experience, familiarity, snippet, etc.) skip #2 and simply cast the returned item from ItemFactory Create directly. In this example, we know a folder connection is a IProjectItem:
//Add a folder connection
string path = @"E:\Pro";
//Cast item to IProjectItem directly
var folderItem = ItemFactory.Instance.Create(path) as IProjectItem;
//Add it
QueuedTask.Run(() => Project.Current.AddItem(folderItem));
Note: calls to ItemFactory.Instance.Create create the project item directly in the following cases:
- FolderConnectionProjectItem (e.g. folders)
- GDBProjectItem (e.g. .gdb, .sde files)
- GeoprocessingProjectItem (e.g. .tbx, .gpkx, .pyt files)
- LocatorsConnectionProjectItem (e.g. .loc files)
- ServerConnectionProjectItem (e.g. .ags, .wcs, .wms, .wfs, .wmts files)
- TaskProjectItem (e.g. task files)
However, these content items still have to be added to the project with AddItem. For example:
//These are equivalent workflows
string folderPath = "@C:\\myDataFolder";
//Get an IProjectItem for the folder
var folderItem = ItemFactory.Instance.Create(path) as IProjectItem;
//Or, get a FolderConnectionProjectItem for the folder
var folderItem = ItemFactory.Instance.Create(path) as FolderConnectionProjectItem;
-- MUST call Project.Current.AddItem if you want to add it! --
Certain file types are silently imported when they are added to a project such as map packages or 10x formatted files (mxds, sxds, styles, etc.) that require conversion. External content types that support importing via the API implement ArcGIS.Desktop.Core.IProjectMultiItem
(refer to topic 15858) and can be passed to Project.Current.ImportItem
to "add" the content to the project as well using the standard Project.Current.AddItem
call. Generally, all 10x file formats that can be imported to Pro support IProjectMultiItem as well as map packages and server connection files.
Using either of Project.Current.ImportItem
or Project.Current.AddItem
with a IProjectMultiItem adds the content to the project*. However, in those cases where more than one item may be created in the project, ImportItem returns the enumeration directly whereas AddItem does not. The canonical case being an mxd that contains both a map and a layout will create two items in the project when it is added.
*Internally, AddItem calls ImportItem for any IProjectMultiItems to perform the "add".
For example, either of these workflows can be used to import an mxd into Pro:
string mxd = @"E:\Pro\USA\OceanBasemap.mxd";
//Either...
var addItem = ItemFactory.Instance.Create(mxd, ItemFactory.ItemType.PathItem) as IProjectItem;
await QueuedTask.Run(() => Project.Current.AddItem(addItem));
//Or...
var importItem = ItemFactory.Instance.Create(mxd, ItemFactory.ItemType.PathItem) as IProjectMultiItem;
var items = await QueuedTask.Run(() => Project.Current.ImportItem(importItem));
//And, of course, MapFactory.Instance.CreateMapFromItem.... not shown
To check whether an item can use Project.Current.ImportItem, test for the presence of the IProjectMultiItem interface:
var item = ItemFactory.Instance.Create(itemPath, ItemFactory.ItemType.PathItem);
//Can it be imported?
if (item is IProjectMultiItem) {
//yes it can
}
//Can it be added?
else if (item is IProjectItem) {
//yes it can
}
The following factories provide "create" methods that consume Items:
- ArcGIS.Desktop.Mapping.MapFactory
- ArcGIS.Desktop.Mapping.LayerFactory
- ArcGIS.Desktop.Mapping.StandaloneTableFactory
This is useful if you are adding layer files or feature classes (as standalone tables) to a map or maps to a project and have already retrieved an item to the external content at some earlier point in your workflow (e.g. you retrieved a layer file item from a browse of a folder connection). For example:
//Use the MapFactory to create a map from an external item (e.g. a mapx file or and mxd)
Item mapItem = ... //retrieved earlier from ItemFactory or from browsing a folder...
return QueuedTask.Run(() => {
// verify that a map can be created from the item
if (MapFactory.Instance.CanCreateMapFrom(mapItem)) {
// creates a new map and adds it to the project. Also opens the mapview
MapFactory.Instance.CreateMapFromItem(mapItem);
}
});
Of course, you can also use overloads on LayerFactory and StandaloneTableFactory that take the physical path ("Uri") to the content without creating an item first
Content can either be accessed via a GetItems<T>
call on the parent item (for example a folder or geodatabase) or on the project instance. If an item has children that can be enumerated with GetItems then its IsContainer
property will be true. Calling GetItems on the project instance enumerates all of the project items - that is, all of the content that has been added to the project at that point in time - whereas calling GetItems on a folder or geodatabase item, for example, enumerates all of the external items that they each contain (regardless of whether the folder or geodatabase have been added to the project or not). GetItems on a "container" (like a folder or geodatabase) always searches one level deep. To perform a multi-level search (e.g. to drill down through a folder hierarchy), the returned Items should be tested for "IsContainer" equals true and their content likewise enumerated with GetItems (recursively) and so on.
As GetItems<T>
is a generic function, it can be constrained to return only items of a particular type using its template parameter "T". This is especially useful when searching the content of the project for just items of a particular type. For example:
//get just the maps - use MapProjectItem
var maps = Project.Current.Getitems<MapProjectItem>();
//get just the database connections - use GDBProjectItem
var gdbs = Project.Current.Getitems<GDBProjectItem>();
//get just the layouts - use LayoutProjectItem
var layouts = Project.Current.Getitems<LayoutProjectItem>();
//etc.
//Just get them all - no constraints
var allItems = Project.Current.GetItems<Item>();
As GetItems<T>
returns an IEnumerable
, the result can be extended with Linq expressions to further refine and filter the retrieved content. For example, this is a search on the first folder connection of a given name in the project for any mxd files it contains:
//Declarations in a view model, for example
private static readonly object _lock = new object();
private ObservableCollection<Item> _mxdResults = = new ObservableCollection<Item>();
...
//Call to BindingOperations to sync access to the ObservableCollection, eg in the ctor
BindingOperations.EnableCollectionSynchronization(_mxdResults , _lock);
...
///<summary>Property for binding of search results</summary>
public ObservableCollection<Item> MxdResults => _mxdResults ;
/// <summary>Performs the search for mxds on the given folder</summary>
private async Task SearchFirstFolderForMxdsAsync(string Folder) {
// find the folder project item - Use Ling FirstOrDefault extension on the returned IEnumerable
var folder = Project.Current.GetItems<FolderConnectionProjectItem>().FirstOrDefault(f => f.Path == Folder);
await QueuedTask.Run(() => {
lock(_lock) {
_mxdResults.Clear();
//Call GetItems to get the folder content (one level deep)
foreach (var item in folder.GetItems()) {
if (item.Name.EndsWith("mxd"))
_mxdResults.Add(item);
}
}
}
Content returned from GetItems are snapshot collections. They are not refreshed if the child content of given parent project item changes (e.g. a new file or feature class is added). Content must be re-queried.
Note: Project also provides a public Task<IEnumerable<Item>> SearchAsync(string query)
function that supports a keyword search of project item content based on the information that a given project item may contain in its metadata (e.g. in its keywords, tags, summary, etc.). Refer to topic 9205 in the API Reference.
The context (i.e. "what is selected") of both the Catalog Pane and the Catalog View can be accessed via the ArcGIS.Desktop.Core.IProjectWindow
interface whenever either the Catalog Pane or View has focus (see topic 14659).
To get the catalog context, first retrieve the active window from the framework application. This will be whichever dockpane or view pane currently has focus. Cast the window to IProjectWindow (using "as"). If the active window is either the Catalog Pane or a Catalog View, the cast will succeed otherwise the window will be null. What is currently selected is accessed off the IProjectWindow.SelectedItems
member.
var window = FrameworkApplication.ActiveWindow as ArcGIS.Desktop.Core.IProjectWindow
var item = window?.SelectedItems.First();
//do something with the selection...
Note: If the item(s) is a project content item, it can be further cast to the relevant "ProjectItem" class (i.e. "project items" like map, style, layout, scene, toolbox, etc.)
Home | API Reference | Requirements | Download | Samples
- Overview of the ArcGIS Pro SDK
- What's New for Developers at 3.4
- Installing ArcGIS Pro SDK for .NET
- Release notes
- Resources
- Pro SDK Videos
- ProSnippets
- ArcGIS Pro API
- ProGuide: ArcGIS Pro Extensions NuGet
Migration
- ProSnippets: Framework
- ProSnippets: DAML
- ProConcepts: Framework
- ProConcepts: Asynchronous Programming in ArcGIS Pro
- ProConcepts: Advanced topics
- ProGuide: Custom settings
- ProGuide: Command line switches for ArcGISPro.exe
- ProGuide: Reusing ArcGIS Pro Commands
- ProGuide: Licensing
- ProGuide: Digital signatures
- ProGuide: Command Search
- ProGuide: Keyboard shortcuts
Add-ins
- ProGuide: Installation and Upgrade
- ProGuide: Your first add-in
- ProGuide: ArcGIS AllSource Project Template
- ProConcepts: Localization
- ProGuide: Content and Image Resources
- ProGuide: Embedding Toolboxes
- ProGuide: Diagnosing ArcGIS Pro Add-ins
- ProGuide: Regression Testing
Configurations
Customization
- ProGuide: The Ribbon, Tabs and Groups
- ProGuide: Buttons
- ProGuide: Label Controls
- ProGuide: Checkboxes
- ProGuide: Edit Boxes
- ProGuide: Combo Boxes
- ProGuide: Context Menus
- ProGuide: Palettes and Split Buttons
- ProGuide: Galleries
- ProGuide: Dockpanes
- ProGuide: Code Your Own States and Conditions
Styling
- ProSnippets: Content
- ProSnippets: Browse Dialog Filters
- ProConcepts: Project Content and Items
- ProConcepts: Custom Items
- ProGuide: Custom Items
- ProGuide: Custom browse dialog filters
- ArcGIS Pro TypeID Reference
- ProSnippets: Editing
- ProConcepts: Editing
- ProConcepts: COGO
- ProConcepts: Annotation Editing
- ProConcepts: Dimension Editing
- ProGuide: Editing Tool
- ProGuide: Sketch Tool With Halo
- ProGuide: Construction Tools with Options
- ProGuide: Annotation Construction Tools
- ProGuide: Annotation Editing Tools
- ProGuide: Knowledge Graph Construction Tools
- ProGuide: Templates
3D Analyst Data
Plugin Datasources
Topology
Linear Referencing
Object Model Diagram
- ProSnippets: Geometry
- ProSnippets: Geometry Engine
- ProConcepts: Geometry
- ProConcepts: Multipatches
- ProGuide: Building Multipatches
Relational Operations
- ProSnippets: Knowledge Graph
- ProConcepts: Knowledge Graph
- ProGuide: Knowledge Graph Construction Tools
Reports
- ProSnippets: Map Authoring
- ProSnippets: Annotation
- ProSnippets: Charts
- ProSnippets: Labeling
- ProSnippets: Renderers
- ProSnippets: Symbology
- ProSnippets: Text Symbols
- ProConcepts: Map Authoring
- ProConcepts: Annotation
- ProConcepts: Dimensions
- ProGuide: Tray buttons
- ProGuide: Custom Dictionary Style
- ProGuide: Geocoding
3D Analyst
CIM
Graphics
Scene
Stream
Voxel
- ProSnippets: Map Exploration
- ProSnippets: Custom Pane with Contents
- ProConcepts: Map Exploration
- ProGuide: Map Pane Impersonation
- ProGuide: TableControl
Map Tools
- ProGuide: Feature Selection
- ProGuide: Identify
- ProGuide: MapView Interaction
- ProGuide: Embeddable Controls
- ProGuide: Custom Pop-ups
- ProGuide: Dynamic Pop-up Menu
Network Diagrams
- ArcGIS Pro API Reference Guide
- ArcGIS Pro SDK (pro.arcgis.com)
- arcgis-pro-sdk-community-samples
- ArcGISPro Registry Keys
- ArcGIS Pro DAML ID Reference
- ArcGIS Pro Icon Reference
- ArcGIS Pro TypeID Reference
- ProConcepts: Distributing Add-Ins Online
- ProConcepts: Migrating to ArcGIS Pro
- FAQ
- Archived ArcGIS Pro API Reference Guides
- Dev Summit Tech Sessions