Hello 🙂
I have a WPF window and I created a "Draw" button. This button minimize the wpf window and I would like to be able to draw some points on simple click, draw the polygon based on points on double click, then set the polygon to a row of the attributes table (in my feature layer) and maximize the wpf window.
I instantiate a "class Draw : MapTool" when I click on the "Draw" button, and try to draw some points on a graphic layer based on an example I found, but it doesn't work (and I don't want to let a graphic layer in my content). I know how to get/set the attributes table but the "draw" functions is the real problem. Is there an other way to do that please ?
Thank you ! 🙂
Solved! Go to Solution.
The attached project performs your workflow using a dockpane (not a WPF window). The project works on 2.7 or newer.
I coded your sample snippet in the code below and also found a bug in my attached solution.
First be bug: The ICommand property in the viewmodel was not named properly it should have been named:
/// <summary>
/// hook existing ArcGIS Pro Tool Button
/// </summary>
public ICommand CmdCreatePolygon => FrameworkApplication.GetPlugInWrapper("CreatePolygon_PolygonTool") as ICommand; Second: here is my test snippet that shows the chained edit operation (on the same layer):
/// <summary>
/// Fires once the user completes the on-screen sketch. In the context of a construction tool the sketch geometry 
/// is used for the shape of the feature.
/// </summary>
/// <param name="geometry">The sketch geometry the user digitized on the screen.</param>
/// <returns></returns>
protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
  // find and use the first polygon layer
  var _polygonLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(lyr => lyr.ShapeType == esriGeometryType.esriGeometryPolygon).FirstOrDefault();
  if (_polygonLayer == null)
  {
	MessageBox.Show("Cannot find a Polygon layer to save constructed geometries");
  }
  if (geometry == null || _polygonLayer == null)
	return Task.FromResult(false);
  var dockPane = Module1.ActiveDockPane;
  if (dockPane == null)
  {
	MessageBox.Show($@"Unable to find the Add Polygon dockpane");
  }
  return QueuedTask.Run(() =>
  {
	// create an edit operation
	var editOperation = new EditOperation
	{
	  Name = $@"Create polygon in '{_polygonLayer.Name}'",
	  ProgressMessage = "Working...",
	  CancelMessage = "Operation canceled",
	  ErrorMessage = "Error creating point"
	};
	long newObjectID = -1;
	// update attributes
	Dictionary<string, object> attributes = new Dictionary<string, object>
	{
	  { "TheString", "First edit operation" }
	};
	// queue the edit operation using the sketch geometry as the shape of the feature 
	editOperation.Create(_polygonLayer, geometry, object_id => newObjectID = object_id);
	dockPane.UpdateStatusText($@"Created a polygon in '{_polygonLayer.Name}'");
	//execute the operation
	if (!editOperation.Execute())
	{
	  return Task.FromResult(false);
	}
	// chain to create a new operation
	var opChain = editOperation.CreateChainedOperation();
	attributes["TheString"] = "Chained operation";
	opChain.Modify (_polygonLayer, newObjectID, attributes);
	return opChain.ExecuteAsync();
  });
}and here is the result, which shows that the chained edit did update the attribute table (by updating the "TheString" field with the "Chained operation" status:
Hello !
Thank you so much ! I work with the SDK 2.6 but it's not a problem. I adapted your code and it works ! I learnt so much things (EditOperation, SketchType, how to do a dock panel in ArcGis Pro).
Thanks again ! 🙂
I have one more question about the EditOperation (code below). I instantiated the EditOperation, then I use editOperation.create to create the new row and to fill it with attributes. If the attributes table panel is open, I see my new line. Nice ! After that, I create a chainedEditOperation to add the geometry with chainedEditOperation.Modify. The row is updated, but if the attributes table panel is open, the view is not updated. I have to close and open again the attributes table to see the geometry in the fields.
Is it possible to update the view like the "Create" method ?
Task t = QueuedTask.Run(() =>
{
   // create an edit operation
   var editOperation = new EditOperation
   {
      Name = $@"Create polygon in '{_polygonLayer.Name}'",
      ProgressMessage = "Working...",
      CancelMessage = "Operation canceled",
      ErrorMessage = "Error creating point"
   };
   long newOid = -1;
   Dictionary<string, object> attributes = new Dictionary<string, object>();
   attributes.Add("Name", EntityNamePreview);
   // queue the edit operation using the sketch geometry as the shape of the       feature and keep the object id
   editOperation.Create(_polygonLayer.GetTable(), attributes, oid => newOid =    oid);
   // if created, fill it with the new polygon
   if (editOperation.Execute())
   {
      var chainedOperation = editOperation.CreateChainedOperation();
      chainedOperation.Modify(_polygonLayer, newOid, PolygonCreated);
      chainedOperation.Execute();
   }
});
while (t.Status != TaskStatus.RanToCompletion) ;
Thank you !
I coded your sample snippet in the code below and also found a bug in my attached solution.
First be bug: The ICommand property in the viewmodel was not named properly it should have been named:
/// <summary>
/// hook existing ArcGIS Pro Tool Button
/// </summary>
public ICommand CmdCreatePolygon => FrameworkApplication.GetPlugInWrapper("CreatePolygon_PolygonTool") as ICommand; Second: here is my test snippet that shows the chained edit operation (on the same layer):
/// <summary>
/// Fires once the user completes the on-screen sketch. In the context of a construction tool the sketch geometry 
/// is used for the shape of the feature.
/// </summary>
/// <param name="geometry">The sketch geometry the user digitized on the screen.</param>
/// <returns></returns>
protected override Task<bool> OnSketchCompleteAsync(Geometry geometry)
{
  // find and use the first polygon layer
  var _polygonLayer = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().Where(lyr => lyr.ShapeType == esriGeometryType.esriGeometryPolygon).FirstOrDefault();
  if (_polygonLayer == null)
  {
	MessageBox.Show("Cannot find a Polygon layer to save constructed geometries");
  }
  if (geometry == null || _polygonLayer == null)
	return Task.FromResult(false);
  var dockPane = Module1.ActiveDockPane;
  if (dockPane == null)
  {
	MessageBox.Show($@"Unable to find the Add Polygon dockpane");
  }
  return QueuedTask.Run(() =>
  {
	// create an edit operation
	var editOperation = new EditOperation
	{
	  Name = $@"Create polygon in '{_polygonLayer.Name}'",
	  ProgressMessage = "Working...",
	  CancelMessage = "Operation canceled",
	  ErrorMessage = "Error creating point"
	};
	long newObjectID = -1;
	// update attributes
	Dictionary<string, object> attributes = new Dictionary<string, object>
	{
	  { "TheString", "First edit operation" }
	};
	// queue the edit operation using the sketch geometry as the shape of the feature 
	editOperation.Create(_polygonLayer, geometry, object_id => newObjectID = object_id);
	dockPane.UpdateStatusText($@"Created a polygon in '{_polygonLayer.Name}'");
	//execute the operation
	if (!editOperation.Execute())
	{
	  return Task.FromResult(false);
	}
	// chain to create a new operation
	var opChain = editOperation.CreateChainedOperation();
	attributes["TheString"] = "Chained operation";
	opChain.Modify (_polygonLayer, newObjectID, attributes);
	return opChain.ExecuteAsync();
  });
}and here is the result, which shows that the chained edit did update the attribute table (by updating the "TheString" field with the "Chained operation" status:
Hello ! 🙂
I see where is my mistake !
Thank you again !!!