ArcGIS Pro SDK (七)编辑 4 行事件
目录
- ArcGIS Pro SDK (七)编辑 4 行事件
- 1 订阅行事件
- 2 在行事件中的映射中的单独表中创建记录
- 3 在行事件中的单独表中创建记录
- 4 修改行事件中的记录 - 使用 Row.Store
- 5 修改行事件中的记录 - 使用 EditOperation.Modify
- 6 确定编辑时几何图形是否更改
- 7 取消删除
环境:Visual Studio 2022 + .NET6 + ArcGIS Pro SDK 3.0
1 订阅行事件
protected void SubscribeRowEvent()
{QueuedTask.Run(() =>{//监听图层的行事件var featLayer = MapView.Active.GetSelectedLayers().First() as FeatureLayer;var layerTable = featLayer.GetTable();//订阅行事件var rowCreateToken = RowCreatedEvent.Subscribe(OnRowCreated, layerTable);var rowChangeToken = RowChangedEvent.Subscribe(OnRowChanged, layerTable);var rowDeleteToken = RowDeletedEvent.Subscribe(OnRowDeleted, layerTable);});
}protected void OnRowCreated(RowChangedEventArgs args)
{
}protected void OnRowChanged(RowChangedEventArgs args)
{
}protected void OnRowDeleted(RowChangedEventArgs args)
{
}
2 在行事件中的映射中的单独表中创建记录
// 使用 RowChangedEventArgs 中的 EditOperation 来追加要执行的操作。
// 你的操作将成为操作的一部分,并合并到撤消堆栈中的一个项目中。private void HookRowCreatedEvent()
{// 订阅 RowCreatedEventTable table = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault().GetTable();RowCreatedEvent.Subscribe(MyRowCreatedEvent, table);
}private void MyRowCreatedEvent(RowChangedEventArgs args)
{// RowEvent 回调总是被 QueuedTask 调用,因此不需要// 在 QueuedTask.Run lambda 中包装代码。// 获取编辑操作var parentEditOp = args.Operation;// 设置一些属性var attribs = new Dictionary<string, object> { };attribs.Add("Layer", "Parcels");attribs.Add("Description", "OID: " + args.Row.GetObjectID().ToString() + " " + DateTime.Now.ToShortTimeString());//在审计表中创建一条记录var sTable = MapView.Active.Map.FindStandaloneTables("EditHistory").First();var table = sTable.GetTable();parentEditOp.Create(table, attribs);
}
3 在行事件中的单独表中创建记录
// 使用 RowChangedEventArgs 中的 EditOperation 来追加要执行的操作。
// 你的操作将成为操作的一部分,并合并到撤消堆栈中的一个项目中。private void HookCreatedEvent()
{// 订阅 RowCreatedEventTable table = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault().GetTable();RowCreatedEvent.Subscribe(OnRowCreatedEvent, table);
}private void OnRowCreatedEvent(RowChangedEventArgs args)
{// RowEvent 回调总是被 QueuedTask 调用,因此不需要// 在 QueuedTask.Run lambda 中包装代码。// 当创建行时更新不在映射中的单独表// 必须使用 ArcGIS.Core.Data API 来编辑表。不要在 RowEvent 回调中使用新的编辑操作try{// 获取编辑操作var parentEditOp = args.Operation;// 设置一些属性var attribs = new Dictionary<string, object> { };attribs.Add("Description", "OID: " + args.Row.GetObjectID().ToString() + " " + DateTime.Now.ToShortTimeString());// 使用新要素的信息更新 Notes 表using (var geoDatabase = new Geodatabase(new FileGeodatabaseConnectionPath(new Uri(Project.Current.DefaultGeodatabasePath)))){using (var table = geoDatabase.OpenDataset<Table>("Notes")){parentEditOp.Create(table, attribs);}}}catch (Exception e){MessageBox.Show($@"Error in OnRowCreated for OID: {args.Row.GetObjectID()} : {e.ToString()}");}
}
4 修改行事件中的记录 - 使用 Row.Store
private void HookRowChangedEvent()
{// 订阅 RowChangedEventTable table = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault().GetTable();RowChangedEvent.Subscribe(OnRowChangedEvent, table);
}private Guid _currentRowChangedGuid = Guid.Empty;
protected void OnRowChangedEvent(RowChangedEventArgs args)
{// RowEvent 回调总是被 QueuedTask 调用,因此不需要// 在 QueuedTask.Run lambda 中包装代码。var row = args.Row;// 检查重入(仅在调用 row.Store 时)if (_currentRowChangedGuid == args.Guid)return;var fldIdx = row.FindField("POLICE_DISTRICT");if (fldIdx != -1){// 验证对“police district”的任何更改// 如果字段验证失败则取消编辑if (row.HasValueChanged(fldIdx)){// 使用无效的区(5)取消编辑var value = row["POLICE_DISTRICT"].ToString();if (value == "5"){// 使用无效的“police district”值取消编辑args.CancelEdit($"Police district {row["POLICE_DISTRICT"]} is invalid");}}// 更新描述字段row["Description"] = "Row Changed";// 这次更新会导致发生另一个 OnRowChanged 事件// 跟踪行 guid 以避免递归_currentRowChangedGuid = args.Guid;row.Store();_currentRowChangedGuid = Guid.Empty;}
}
5 修改行事件中的记录 - 使用 EditOperation.Modify
private void HookChangedEvent()
{// 订阅 RowChangedEventTable table = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault().GetTable();RowChangedEvent.Subscribe(MyRowChangedEvent, table);
}private void MyRowChangedEvent(RowChangedEventArgs args)
{// RowEvent 回调总是被 QueuedTask 调用,因此不需要// 在 QueuedTask.Run lambda 中包装代码。// 修改已创建行上的字段示例var parentEditOp = args.Operation;// 避免递归if (_lastEdit != args.Guid){// 在更改时更新字段parentEditOp.Modify(args.Row, "ZONING", "New");_lastEdit = args.Guid;}
}
6 确定编辑时几何图形是否更改
private static FeatureLayer featureLayer;
private static void DetermineGeometryChange()
{featureLayer = MapView.Active?.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault();if (featureLayer == null)return;QueuedTask.Run(() =>{//监听行更改事件ArcGIS.Desktop.Editing.Events.RowChangedEvent.Subscribe(OnRowChangedEvent2, featureLayer.GetTable());});
}
private static void OnRowChangedEvent2(RowChangedEventArgs args)
{// RowEvent 回调总是被 QueuedTask 调用,因此不需要// 在 QueuedTask.Run lambda 中包装代码。//获取图层的定义var lyrDefn = featureLayer.GetFeatureClass().GetDefinition();//获取要素类的形状字段string shapeField = lyrDefn.GetShapeField();//形状字段的索引var shapeIndex = lyrDefn.FindField(shapeField);//修改行的原始几何var geomOrig = args.Row.GetOriginalValue(shapeIndex) as Geometry;//修改行的新几何var geomNew = args.Row[shapeIndex] as Geometry;//比较两者bool shapeChanged = geomOrig.IsEqual(geomNew);
}
7 取消删除
public static void StopADelete()
{// 订阅适当表的 RowDeletedEventTable table = MapView.Active.Map.GetLayersAsFlattenedList().OfType<FeatureLayer>().FirstOrDefault().GetTable();RowDeletedEvent.Subscribe(OnRowDeletedEvent, table);
}private static void OnRowDeletedEvent(RowChangedEventArgs args)
{// RowEvent 回调总是被 QueuedTask 调用,因此不需要// 在 QueuedTask.Run lambda 中包装代码。var row = args.Row;// 如果要素位于 5 区,则取消删除var fldIdx = row.FindField("POLICE_DISTRICT");if (fldIdx != -1){var value = row[fldIdx].ToString();if (value == "5"){//带对话框取消// 注意 - 无法取消托管和标准要素服务上的要素编辑。args.CancelEdit("Delete Event\nAre you sure", true);// 或不带对话框取消// args.CancelEdit();}}
}