ProGuide Construction Tools with Options - Esri/arcgis-pro-sdk GitHub Wiki
Language: C#
Subject: Editing
Contributor: ArcGIS Pro SDK Team <[email protected]>
Organization: Esri, http://www.esri.com
Date: 10/06/2024
ArcGIS Pro: 3.4
Visual Studio: 2022
This ProGuide demonstrates how to create a construction tool with options which allows users to input parameter values to the tool at run-time. The abstract class ToolOptionsEmbeddableControl
provides all that is needed to implement this feature. Use this in conjunction with the daml category esri_editing_tool_options
to gain the ability to configure construction tools with options which can be saved as part of the project.
The code used to illustrate this add-in can be found at Construction Tool with Options Sample.
Prerequisites
- Download and install the sample data required for this guide as instructed in Arcgis Pro SDK Community Samples Releases.
- Create a new ArcGIS Pro Module Add-in, and name the project ConstructionToolWithOptions. If you are not familiar with the ArcGIS Pro SDK, you can follow the steps in the ProGuide Build your first add-in to get started.
- Add a new ArcGIS Pro Add-ins | ArcGIS Pro Construction Tool item to the add-in project, and name the item BufferedLineTool.
- Add a new ArcGIS Pro Add-ins | ArcGIS Pro Embeddable Control item to the add-in project, and name the item BufferedLineToolOptions.
Step 1
Change the construction tool to create polygon features by buffering a sketch line geometry. You will achieve this by performing the following.
Modify the config.daml file tool item
- Change the caption to "Buffered Line".
- Change the categoryRefID to "esri_editing_construction_polygon" indicating you will create polygon features.
- Change the tooltip heading to "Buffered Line" and the ToolTip text to "Create a polygon with a fixed buffer.".
- Your tool entry will have a content tag with a guid attribute. Don't change this attribute.
<controls>
<!-- add your controls here -->
<tool id="ConstructionToolWithOptions_BufferedLineTool"
categoryRefID="esri_editing_construction_polygon"
caption="Buffered Line" className="BufferedLineTool"
loadOnClick="true"
smallImage="Images\GenericButtonRed16.png" largeImage="Images\GenericButtonRed32.png">
<tooltip heading="Buffered Line">Create a polygon with a fixed buffer.<disabledText /></tooltip>
<content guid="ad2f2bbd-2185-4cca-a4b4-b137f6bc969a" /> <!-- your guid value will be different -->
</tool>
</controls>
Modify the BufferedLineTool.cs file as follows
- Change the
SketchType
in the constructor to beSketchGeometryType.Line
. This is the geometry of the map tool feedback used to symbolize the user interaction (i.e. the user will sketching a line).
public BufferedLineTool()
{
IsSketchTool = true;
UseSnapping = true;
// Select the type of construction tool you wish to implement.
// Make sure that the tool is correctly registered with the
// correct component category type in the daml
SketchType = SketchGeometryType.Line;
...
}
- Modify OnSketchCompleteAsync so that the line sketch geometry is buffered to a polygon by calling
GeometryEngine.Instance.Buffer
with a preset distance value. The ability to allow user defined buffer distances as part of the tool will be covered in steps later in this guide. Pass this buffered geometry to the create operation.
private double BufferDistance = 25.0;
/// <summary>
/// Called when the sketch finishes. This is where we will create the sketch operation and then execute it.
/// </summary>
/// <param name="geometry">The geometry created by the sketch.</param>
/// <returns>A Task returning a Boolean indicating if the sketch complete event was successfully handled.</returns>
protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
if (CurrentTemplate == null || geometry == null)
return Task.FromResult(false);
// create the buffered geometry
Geometry bufferedGeometry = GeometryEngine.Instance.Buffer(geometry, BufferDistance);
// Create an edit operation
var createOperation = new EditOperation();
createOperation.Name = string.Format("Create {0}", CurrentTemplate.Layer.Name);
createOperation.SelectNewFeatures = true;
// Queue feature creation
createOperation.Create(CurrentTemplate, bufferedGeometry);
// Execute the operation
return createOperation.ExecuteAsync();
}
Build your add-in. Debug the add-in. Open the C:\Data\FeatureTest\FeatureTest.aprx project. Verify that your construction tool appears on the polygon layer. Activate the tool and create a new polygon feature by sketching a line.
Step 2
Add the ability to configure the tools buffer distance by using the embeddable control you previously added. The first step is to register the embeddable control as being part of the daml category tool options category - esri_editing_tool_options
.
Modify the config.daml file
- Change the embeddable control BufferedLineToolOptions definition by registering the component with the
esri_editing_tool_options
category rather than theesri_embeddableControls
category.
<updateCategory refID="esri_editing_tool_options">
<insertComponent id="ConstructionToolWithOptions_BufferedLineToolOptions" className="BufferedLineToolOptionsViewModel">
<content className="BufferedLineToolOptionsView" />
</insertComponent>
</updateCategory>
Secondly we need to change the BufferedLineToolOptions view to obtain a buffer distance from the user.
- Modify the BufferedLineToolOptions.xaml file and replace the TextBlock tag so the Grid definition looks like below
<Grid Margin="30,0">
<StackPanel Orientation="Horizontal" VerticalAlignment="Top">
<Label Content="Buffer distance:" Foreground="{StaticResource Esri_Gray155}" />
<TextBox Text="{Binding Path=Buffer, UpdateSourceTrigger=PropertyChanged}" Margin="6,0,0,0" Width="75"/>
</StackPanel>
</Grid>
Finally we need to modify the BufferedLineToolOptions view model to inherit from the ToolOptionsEmbeddableControl
rather than the EmbeddableControl class. The ToolOptionsEmbeddableControl class provides the ability to read and write properties into a tool's option set. At 2.x the same ability of reading and writing properties to a tool's option set was provided by adding the IEditingCreateToolControl interface to the class definition.
Modify the BufferedLineToolOptionsViewModel.cs file and replace the EmbeddableControl class with the ToolOptionsEmbeddableControl class to change the class definition. Override the IsAutoOpen
and LoadFromToolOptions
functions to fully implement the class.
//At 2.x -
//internal class BufferedLineToolOptionsViewModel : EmbeddableControl, IEditingCreateToolControl
internal class BufferedLineToolOptionsViewModel : ToolOptionsEmbeddableControl
{
....
public override bool IsAutoOpen(string toolID)
{
return true;
}
protected override Task LoadFromToolOptions()
{
throw new NotImplementedException();
}
}
The IsAutoOpen function indicates whether the tool options view should auto-open in the Active Template pane when the construction tool is activated. The LoadFromToolOptions function is called before the embeddable control is opened within the ActiveTemplate pane allowing you to configure your options view from the values stored with the tool. Add a function InitializeOptions to be called from LoadFromToolOptions. InitializeOptions will be completed in a few steps.
protected override Task LoadFromToolOptions()
{
InitializeOptions();
return Task.CompletedTask;
}
private void InitializeOptions()
{
}
Our options contains a Buffer property which will bind in the xaml. Add this property to the class. When setting the property value, utilize the SetToolOption
method on the ToolOptionsEmbeddableControl class using a key for the property name. SetToolOption writes the property key and value into the ToolOptions for the tool.
nternal const string BufferOptionName = nameof(Buffer);
// binds in xaml
private double _buffer;
public double Buffer
{
get { return _buffer; }
set
{
if (SetProperty(ref _buffer, value))
{
IsDirty = true;
SetToolOption(BufferOptionName, value);
}
}
}
Finally complete the InitializeOptions method to retrieve the tool option value and assign to the internal variable _buffer. Use the GetToolOption
method using the same property key to retrieve the property value from the ToolOptions.
internal const double DefaultBuffer = 25.0;
private void InitializeOptions()
{
double? buffer = GetToolOption<double?>(BufferOptionName, DefaultBuffer, null);
_buffer = buffer.Value;
}
Step 3
Now that the options view and view model are defined the final step is to link the options to the construction tool. This can be accomplished by the following
Modify the config.daml file
- Change the tool definition to include a reference to the options by adding the
toolOptionsID
attribute to the content tag
<tool id="ConstructionToolWithOptions_BufferedLineTool" categoryRefID="esri_editing_construction_point"
caption="Buffered Line" className="BufferedLineTool"
loadOnClick="true"
smallImage="Images\GenericButtonRed16.png" largeImage="Images\GenericButtonRed32.png">
<tooltip heading="Buffered Line">Create a polygon with a fixed buffer.<disabledText /></tooltip>
<content guid="..." toolOptionsID="ConstructionToolWithOptions_BufferedLineToolOptions" />
</tool>
Return to the BufferedLineTool.cs file. Replace the previously declared BufferDistance variable with the following to obtain the buffer distance from the user input value on the options view.
#region Tool Options
// get the set of tool options for this tool
private ReadOnlyToolOptions ToolOptions => CurrentTemplate?.GetToolOptions(ID);
private double BufferDistance
{
get
{
if (ToolOptions == null)
return BufferedLineToolOptionsViewModel.DefaultBuffer;
// get the option value using the option key.
// supply a default value if the tool option doesn't exist
return ToolOptions.GetProperty(BufferedLineToolOptionsViewModel.BufferOptionName, BufferedLineToolOptionsViewModel.DefaultBuffer);
}
}
#endregion
Rebuild the add-in. Fix any compilation errors. Run the debugger and start ArcGIS Pro. Open the C:\Data\FeatureTest\FeatureTest.aprx project. Choose the construction tool and see the options page appear. Enter a buffer distance and sketch a line. See the buffered feature created. Enter a different distance and sketch another line. Choose a different construction tool for the template. Then return to the Buffer Line Tool. Ensure that your buffer distance is retained.
Additional examples of this pattern have been included in the sample Construction Tool with Options.