private void DynamoRevitTestResultsView_OnClosed(object sender, EventArgs e) { IdlePromise.ExecuteOnIdle(delegate { DynamoLogger.Instance.FinishLogging(); }); }
private void selectButton_Click(object sender, RoutedEventArgs e) { _selectButton.IsEnabled = false; IdlePromise.ExecuteOnIdle( delegate { OnSelectClick(); _selectButton.IsEnabled = true; }); }
private void DrawToAlternateContext(List <GeometryObject> geoms) { Type geometryElementType = typeof(GeometryElement); MethodInfo[] geometryElementTypeMethods = geometryElementType.GetMethods(BindingFlags.Static | BindingFlags.Public); var method = geometryElementTypeMethods.FirstOrDefault(x => x.Name == "SetForTransientDisplay"); if (method == null) { return; } var styles = new FilteredElementCollector(dynRevitSettings.Doc.Document); styles.OfClass(typeof(GraphicsStyle)); var gStyle = styles.ToElements().FirstOrDefault(x => x.Name == "Dynamo"); IdlePromise.ExecuteOnIdle( () => { dynRevitSettings.Controller.InitTransaction(); if (_keeperId != ElementId.InvalidElementId) { dynRevitSettings.Doc.Document.Delete(_keeperId); _keeperId = ElementId.InvalidElementId; } var argsM = new object[4]; argsM[0] = dynRevitSettings.Doc.Document; argsM[1] = ElementId.InvalidElementId; argsM[2] = geoms; if (gStyle != null) { argsM[3] = gStyle.Id; } else { argsM[3] = ElementId.InvalidElementId; } _keeperId = (ElementId)method.Invoke(null, argsM); //keeperId = GeometryElement.SetForTransientDisplay(dynRevitSettings.Doc.Document, ElementId.InvalidElementId, geoms, // ElementId.InvalidElementId); dynRevitSettings.Controller.EndTransaction(); }); }
protected override void Run(List <NodeModel> topElements, FScheme.Expression runningExpression) { var model = (DynamoRevitViewModel)DynamoViewModel; //If we are not running in debug... if (!DynamoViewModel.RunInDebug) { //Do we need manual transaction control? bool manualTrans = topElements.Any(CheckManualTransaction.TraverseUntilAny); //Can we avoid running everything in the Revit Idle thread? bool noIdleThread = manualTrans || !topElements.Any(CheckRequiresTransaction.TraverseUntilAny); //If we don't need to be in the idle thread... if (noIdleThread || IsTestMode) { //DynamoLogger.Instance.Log("Running expression in evaluation thread..."); TransMode = TransactionMode.Manual; //Manual transaction control if (IsTestMode) { TransMode = TransactionMode.Automatic; } InIdleThread = false; //Not in idle thread at the moment base.Run(topElements, runningExpression); //Just run the Run Delegate } else //otherwise... { //DynamoLogger.Instance.Log("Running expression in Revit's Idle thread..."); TransMode = TransactionMode.Automatic; //Automatic transaction control Debug.WriteLine("Adding a run to the idle stack."); InIdleThread = true; //Now in the idle thread. IdlePromise.ExecuteOnIdle( () => base.Run(topElements, runningExpression), false); //Execute the Run Delegate in the Idle thread. } } else //If we are in debug mode... { TransMode = TransactionMode.Debug; //Debug transaction control InIdleThread = true; //Everything will be evaluated in the idle thread. DynamoLogger.Instance.Log("Running expression in debug."); //Execute the Run Delegate. base.Run(topElements, runningExpression); } }
protected override void Run(IEnumerable <dynNodeModel> topElements, FScheme.Expression runningExpression) { //If we are not running in debug... if (!this.DynamoViewModel.RunInDebug) { //Do we need manual transaction control? bool manualTrans = topElements.Any((DynamoViewModel as DynamoRevitViewModel).CheckManualTransaction.TraverseUntilAny); //Can we avoid running everything in the Revit Idle thread? bool noIdleThread = manualTrans || !topElements.Any((DynamoViewModel as DynamoRevitViewModel).CheckRequiresTransaction.TraverseUntilAny); //If we don't need to be in the idle thread... if (noIdleThread || this.Testing) { DynamoLogger.Instance.Log("Running expression in evaluation thread..."); (DynamoViewModel as DynamoRevitViewModel).TransMode = DynamoRevitViewModel.TransactionMode.Manual; //Manual transaction control if (this.Testing) { (DynamoViewModel as DynamoRevitViewModel).TransMode = DynamoRevitViewModel.TransactionMode.Automatic; } this.InIdleThread = false; //Not in idle thread at the moment base.Run(topElements, runningExpression); //Just run the Run Delegate } else //otherwise... { DynamoLogger.Instance.Log("Running expression in Revit's Idle thread..."); (DynamoViewModel as DynamoRevitViewModel).TransMode = DynamoRevitViewModel.TransactionMode.Automatic; //Automatic transaction control Debug.WriteLine("Adding a run to the idle stack."); this.InIdleThread = true; //Now in the idle thread. IdlePromise.ExecuteOnIdle(new Action( () => base.Run(topElements, runningExpression)), false); //Execute the Run Delegate in the Idle thread. } } else //If we are in debug mode... { (DynamoViewModel as DynamoRevitViewModel).TransMode = DynamoRevitViewModel.TransactionMode.Debug; //Debug transaction control this.InIdleThread = true; //Everything will be evaluated in the idle thread. dynSettings.Controller.DynamoViewModel.Log("Running expression in debug."); //Execute the Run Delegate. base.Run(topElements, runningExpression); } }
/// <summary> /// Destroy all elements belonging to this dynElement /// </summary> public override void Destroy() { var controller = dynRevitSettings.Controller; IdlePromise.ExecuteOnIdle( delegate { controller.InitTransaction(); try { runCount = 0; var query = controller.DynamoViewModel.Model.HomeSpace.Nodes .Where(x => x is dynFunctionWithRevit) .Select(x => (x as dynFunctionWithRevit).ElementsContainer) .Where(c => c.HasElements(GUID)) .SelectMany(c => c[GUID]); foreach (var els in query) { foreach (ElementId e in els) { try { dynRevitSettings.Doc.Document.Delete(e); } catch (Autodesk.Revit.Exceptions.InvalidOperationException) { //TODO: Flesh out? } } els.Clear(); } } catch (Exception ex) { dynSettings.Controller.DynamoViewModel.Log( "Error deleting elements: " + ex.GetType().Name + " -- " + ex.Message ); } controller.EndTransaction(); WorkSpace.Modified(); }, true ); }
void CleanupVisualizations(object sender, EventArgs e) { IdlePromise.ExecuteOnIdle( () => { dynRevitSettings.Controller.InitTransaction(); if (_keeperId != ElementId.InvalidElementId) { dynRevitSettings.Doc.Document.Delete(_keeperId); _keeperId = ElementId.InvalidElementId; } dynRevitSettings.Controller.EndTransaction(); }); }
/// <summary> /// Destroy all elements belonging to this dynElement /// </summary> public override void Destroy() { var controller = dynRevitSettings.Controller; IdlePromise.ExecuteOnIdle( delegate { controller.InitTransaction(); try { _runCount = 0; //TODO: Re-enable once similar functionality is fleshed out for dynFunctionWithRevit //var query = controller.DynamoViewModel.Model.HomeSpace.Nodes // .OfType<dynFunctionWithRevit>() // .Select(x => x.ElementsContainer) // .Where(c => c.HasElements(GUID)) // .SelectMany(c => c[GUID]); foreach (var els in elements) { foreach (ElementId e in els) { try { dynRevitSettings.Doc.Document.Delete(e); } catch (Autodesk.Revit.Exceptions.InvalidOperationException) { //TODO: Flesh out? } } els.Clear(); } } catch (Exception ex) { DynamoLogger.Instance.Log( "Error deleting elements: " + ex.GetType().Name + " -- " + ex.Message ); } controller.EndTransaction(); WorkSpace.Modified(); }); }
//private void DrawContainers(Value val, string id) //{ // if (val.IsList) // { // foreach (Value v in ((Value.List)val).Item) // { // DrawContainers(v, id); // } // } // if (val.IsContainer) // { // var drawable = ((Value.Container)val).Item; // //support drawing XYZs geometry objects or LibG graphic items // if(drawable is XYZ || drawable is GeometryObject || drawable is GraphicItem ) // { // VisualizationManager.Visualizations[id].Geometry.Add(drawable); // } // } //} Value newEval(bool dirty, string script, dynamic bindings, dynamic inputs) { bool transactionRunning = Transaction != null && Transaction.GetStatus() == TransactionStatus.Started; Value result = null; if (dynRevitSettings.Controller.InIdleThread) { result = _oldPyEval(dirty, script, bindings, inputs); } else { result = IdlePromise <Value> .ExecuteOnIdle( () => _oldPyEval(dirty, script, bindings, inputs)); } if (transactionRunning) { if (!IsTransactionActive()) { InitTransaction(); } else { var ts = Transaction.GetStatus(); if (ts != TransactionStatus.Started) { if (ts != TransactionStatus.RolledBack) { CancelTransaction(); } InitTransaction(); } } } else if (DynamoViewModel.RunInDebug) { if (IsTransactionActive()) { EndTransaction(); } } return(result); }
public override void Destroy() { IdlePromise.ExecuteOnIdle( delegate { dynRevitSettings.Controller.InitTransaction(); try { ElementsContainer.DestroyAll(); } catch (Exception ex) { DynamoLogger.Instance.Log( "Error deleting elements: " + ex.GetType().Name + " -- " + ex.Message); } dynRevitSettings.Controller.EndTransaction(); WorkSpace.Modified(); }); }
protected override void OnEvaluationCompleted(object sender, EventArgs e) { base.OnEvaluationCompleted(sender, e); //Cleanup Delegate Action cleanup = delegate { //TODO: perhaps this should occur inside of ResetRuns in the event that // there is nothing to be deleted? InitTransaction(); //Initialize a transaction (if one hasn't been aleady) //Reset all elements var query = dynSettings.Controller.DynamoModel.AllNodes .OfType <RevitTransactionNode>(); foreach (RevitTransactionNode element in query) { element.ResetRuns(); } ////// /* FOR NON-DEBUG RUNS, THIS IS THE ACTUAL END POINT FOR DYNAMO TRANSACTION */ ////// EndTransaction(); //Close global transaction. }; //If we're in a debug run or not already in the idle thread, then run the Cleanup Delegate //from the idle thread. Otherwise, just run it in this thread. if (dynSettings.Controller.DynamoViewModel.RunInDebug || !InIdleThread && !Testing) { IdlePromise.ExecuteOnIdle(cleanup, false); } else { cleanup(); } }
protected override void OnEvaluationCompleted() { base.OnEvaluationCompleted(); //Cleanup Delegate Action cleanup = delegate { this.InitTransaction(); //Initialize a transaction (if one hasn't been aleady) //Reset all elements foreach (var element in dynSettings.Controller.DynamoViewModel.AllNodes) { if (element is dynRevitTransactionNode) { (element as dynRevitTransactionNode).ResetRuns(); } } ////// /* FOR NON-DEBUG RUNS, THIS IS THE ACTUAL END POINT FOR DYNAMO TRANSACTION */ ////// this.EndTransaction(); //Close global transaction. }; //If we're in a debug run or not already in the idle thread, then run the Cleanup Delegate //from the idle thread. Otherwise, just run it in this thread. if (dynSettings.Controller.DynamoViewModel.RunInDebug || !InIdleThread && !this.Testing) { IdlePromise.ExecuteOnIdle(cleanup, false); } else { cleanup(); } }
public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements) { AppDomain.CurrentDomain.AssemblyResolve += Dynamo.Utilities.AssemblyHelper.CurrentDomain_AssemblyResolve; AppDomain.CurrentDomain.AssemblyResolve += DynamoRaaS.AssemblyHelper.ResolveAssemblies; //Add an assembly load step for the System.Windows.Interactivity assembly //Revit owns a version of this as well. Adding our step here prevents a duplicative //load of the dll at a later time. var assLoc = Assembly.GetExecutingAssembly().Location; var interactivityPath = Path.Combine(Path.GetDirectoryName(assLoc), "System.Windows.Interactivity.dll"); var interactivityAss = Assembly.LoadFrom(interactivityPath); //When a user double-clicks the Dynamo icon, we need to make //sure that we don't create another instance of Dynamo. if (isRunning) { Debug.WriteLine("Dynamo is already running."); if (dynamoView != null) { dynamoView.Focus(); } return(Result.Succeeded); } isRunning = true; try { m_revit = revit.Application; m_doc = m_revit.ActiveUIDocument; #region default level Level defaultLevel = null; var fecLevel = new FilteredElementCollector(m_doc.Document); fecLevel.OfClass(typeof(Level)); defaultLevel = fecLevel.ToElements()[0] as Level; #endregion dynRevitSettings.Revit = m_revit; dynRevitSettings.Doc = m_doc; dynRevitSettings.DefaultLevel = defaultLevel; IdlePromise.ExecuteOnIdle(delegate { //get window handle IntPtr mwHandle = Process.GetCurrentProcess().MainWindowHandle; Regex r = new Regex(@"\b(Autodesk |Structure |MEP |Architecture )\b"); string context = r.Replace(m_revit.Application.VersionName, ""); //they changed the application version name conventions for vasari //it no longer has a version year so we can't compare it to other versions //TODO:come up with a more stable way to test for Vasari beta 3 if (context == "Vasari") { context = "Vasari 2014"; } var units = new UnitsManager { HostApplicationInternalAreaUnit = DynamoAreaUnit.SquareFoot, HostApplicationInternalLengthUnit = DynamoLengthUnit.DecimalFoot, HostApplicationInternalVolumeUnit = DynamoVolumeUnit.CubicFoot }; dynamoController = new DynamoController_Revit(DynamoRevitApp.env, DynamoRevitApp.Updater, typeof(DynamoRevitViewModel), context, units); dynamoView = new DynamoView { DataContext = dynamoController.DynamoViewModel }; dynamoController.UIDispatcher = dynamoView.Dispatcher; //set window handle and show dynamo new WindowInteropHelper(dynamoView).Owner = mwHandle; handledCrash = false; dynamoView.WindowStartupLocation = WindowStartupLocation.Manual; Rectangle bounds = Screen.PrimaryScreen.Bounds; dynamoView.Left = dynamoViewX ?? bounds.X; dynamoView.Top = dynamoViewY ?? bounds.Y; dynamoView.Width = dynamoViewWidth ?? 1000.0; dynamoView.Height = dynamoViewHeight ?? 800.0; dynamoView.Show(); dynamoView.Dispatcher.UnhandledException -= DispatcherOnUnhandledException; dynamoView.Dispatcher.UnhandledException += DispatcherOnUnhandledException; dynamoView.Closing += dynamoView_Closing; dynamoView.Closed += dynamoView_Closed; //revit.Application.ViewActivated += new EventHandler<Autodesk.Revit.UI.Events.ViewActivatedEventArgs>(Application_ViewActivated); revit.Application.ViewActivating += Application_ViewActivating; }); } catch (Exception ex) { isRunning = false; MessageBox.Show(ex.ToString()); DynamoLogger.Instance.Log(ex.Message); DynamoLogger.Instance.Log(ex.StackTrace); DynamoLogger.Instance.Log("Dynamo log ended " + DateTime.Now.ToString()); return(Result.Failed); } return(Result.Succeeded); }
protected override Expression compileBody( Dictionary <INode, string> symbols, Dictionary <INode, List <INode> > letEntries, HashSet <string> initializedIds, HashSet <string> conditionalIds) { var arg = arguments.First().Value.compile( symbols, letEntries, initializedIds, conditionalIds); //idle :: (() -> A) -> A //Evaluates the given function in the Revit Idle thread. var idle = Expression.NewFunction_E( FSharpFunc <FSharpList <Value>, Value> .FromConverter( args => { var f = (args[0] as Value.Function).Item; if (dynSettings.Controller.DynamoViewModel.RunInDebug) { return(f.Invoke(FSharpList <Value> .Empty)); } return(IdlePromise <Value> .ExecuteOnIdle( () => f.Invoke(FSharpList <Value> .Empty))); })); //startTransaction :: () -> () //Starts a Dynamo Transaction. var startTransaction = Expression.NewFunction_E( FSharpFunc <FSharpList <Value>, Value> .FromConverter( _ => { if (_node.Controller.RunCancelled) { throw new CancelEvaluationException(false); } if (!dynSettings.Controller.DynamoViewModel.RunInDebug) { dynRevitSettings.Controller.InIdleThread = true; dynRevitSettings.Controller.InitTransaction(); } return(Value.NewDummy("started transaction")); })); //endTransaction :: () -> () //Ends a Dynamo Transaction. var endTransaction = Expression.NewFunction_E( FSharpFunc <FSharpList <Value>, Value> .FromConverter( _ => { if (!dynRevitSettings.Controller.DynamoViewModel.RunInDebug) { dynRevitSettings.Controller.EndTransaction(); dynRevitSettings.Controller.InIdleThread = false; dynSettings.Controller.DynamoViewModel.OnRequestLayoutUpdate(this, EventArgs.Empty); _node.ValidateConnections(); } else { _node.setDirty(false); } return(Value.NewDummy("ended transaction")); })); /* (define (idleArg) * (startTransaction) * (let ((a <arg>)) * (endTransaction) * a)) */ var idleArg = Expression.NewFun( FSharpList <FScheme.Parameter> .Empty, Expression.NewBegin( Utils.SequenceToFSharpList(new List <Expression> { Expression.NewList_E( Utils.SequenceToFSharpList( new List <Expression> { startTransaction })), Expression.NewLet( Utils.SequenceToFSharpList( new List <string> { "__result" }), Utils.SequenceToFSharpList( new List <Expression> { arg }), Expression.NewBegin( Utils.SequenceToFSharpList( new List <Expression> { Expression.NewList_E( Utils.SequenceToFSharpList( new List <Expression> { endTransaction })), Expression.NewId("__result") }))) }))); // (idle idleArg) return(Expression.NewList_E( Utils.SequenceToFSharpList(new List <Expression> { idle, idleArg }))); }
protected override void __eval_internal(FSharpList <Value> args, Dictionary <PortData, Value> outPuts) { var controller = dynRevitSettings.Controller; if (controller.TransMode != TransactionMode.Debug) { #region no debug if (controller.TransMode == TransactionMode.Manual && !controller.IsTransactionActive()) { throw new Exception("A Revit transaction is required in order evaluate this element."); } controller.InitTransaction(); base.__eval_internal(args, outPuts); foreach (ElementId eid in _deletedIds) { controller.RegisterSuccessfulDeleteHook( eid, onSuccessfulDelete); } _deletedIds.Clear(); #endregion } else { #region debug DynamoLogger.Instance.Log("Starting a debug transaction for element: " + NickName); IdlePromise.ExecuteOnIdle( delegate { controller.InitTransaction(); try { base.__eval_internal(args, outPuts); foreach (ElementId eid in _deletedIds) { controller.RegisterSuccessfulDeleteHook( eid, onSuccessfulDelete); } _deletedIds.Clear(); controller.EndTransaction(); ValidateConnections(); } catch (Exception) { controller.CancelTransaction(); throw; } }, false); #endregion } }
public Result Execute(ExternalCommandData revit, ref string message, ElementSet elements) { //When a user double-clicks the Dynamo icon, we need to make //sure that we don't create another instance of Dynamo. if (isRunning) { Debug.WriteLine("Dynamo is already running."); if (dynamoView != null) { dynamoView.Focus(); } return(Result.Succeeded); } isRunning = true; DynamoLogger.Instance.StartLogging(); try { m_revit = revit.Application; m_doc = m_revit.ActiveUIDocument; #region default level Level defaultLevel = null; var fecLevel = new FilteredElementCollector(m_doc.Document); fecLevel.OfClass(typeof(Level)); defaultLevel = fecLevel.ToElements()[0] as Level; #endregion dynRevitSettings.Revit = m_revit; dynRevitSettings.Doc = m_doc; dynRevitSettings.DefaultLevel = defaultLevel; IdlePromise.ExecuteOnIdle(delegate { //get window handle IntPtr mwHandle = Process.GetCurrentProcess().MainWindowHandle; //show the window Regex r = new Regex(@"\b(Autodesk |Structure |MEP |Architecture )\b"); string context = r.Replace(m_revit.Application.VersionName, ""); //they changed the application version name conventions for vasari //it no longer has a version year so we can't compare it to other versions //TODO:come up with a more stable way to test for Vasari beta 3 if (context == "Vasari") { context = "Vasari 2014"; } dynamoController = new DynamoController_Revit(DynamoRevitApp.env, DynamoRevitApp.updater, typeof(DynamoRevitViewModel), context); dynSettings.Bench = new DynamoView { DataContext = dynamoController.DynamoViewModel }; dynamoController.UIDispatcher = dynSettings.Bench.Dispatcher; dynamoView = dynSettings.Bench; //set window handle and show dynamo new WindowInteropHelper(dynamoView).Owner = mwHandle; handledCrash = false; dynamoView.WindowStartupLocation = WindowStartupLocation.Manual; Rectangle bounds = Screen.PrimaryScreen.Bounds; dynamoView.Left = dynamoViewX ?? bounds.X; dynamoView.Top = dynamoViewY ?? bounds.Y; dynamoView.Width = dynamoViewWidth ?? 1000.0; dynamoView.Height = dynamoViewHeight ?? 800.0; dynamoView.Show(); dynamoView.Dispatcher.UnhandledException += DispatcherOnUnhandledException; dynamoView.Closing += dynamoView_Closing; dynamoView.Closed += dynamoView_Closed; }); } catch (Exception ex) { isRunning = false; MessageBox.Show(ex.ToString()); DynamoLogger.Instance.Log(ex.Message); DynamoLogger.Instance.Log(ex.StackTrace); DynamoLogger.Instance.Log("Dynamo log ended " + DateTime.Now.ToString()); return(Result.Failed); } return(Result.Succeeded); }
protected override void OnEvaluationCompleted(object sender, EventArgs e) { base.OnEvaluationCompleted(sender, e); //Cleanup Delegate Action cleanup = delegate { //TODO: perhaps this should occur inside of ResetRuns in the event that // there is nothing to be deleted? InitTransaction(); //Initialize a transaction (if one hasn't been aleady) //Reset all elements var query = dynSettings.Controller.DynamoModel.AllNodes .OfType <RevitTransactionNode>(); foreach (RevitTransactionNode element in query) { element.ResetRuns(); } ////// /* FOR NON-DEBUG RUNS, THIS IS THE ACTUAL END POINT FOR DYNAMO TRANSACTION */ ////// EndTransaction(); //Close global transaction. }; //Rename Delegate Action rename = delegate { InitTransaction(); foreach (var kvp in ElementNameStore) { //find the element and rename it Element el = null; if (dynUtils.TryGetElement(kvp.Key, out el)) { //if the element is not stored with a unique name //add a unique suffix to it try { if (el is Autodesk.Revit.DB.ReferencePlane) { var rp = el as Autodesk.Revit.DB.ReferencePlane; rp.Name = kvp.Value; } } catch (Exception ex) { if (el is Autodesk.Revit.DB.ReferencePlane) { var rp = el as Autodesk.Revit.DB.ReferencePlane; rp.Name = kvp.Value + "_" + Guid.NewGuid(); } } } } ElementNameStore.Clear(); EndTransaction(); }; //If we're in a debug run or not already in the idle thread, then run the Cleanup Delegate //from the idle thread. Otherwise, just run it in this thread. if (dynSettings.Controller.DynamoViewModel.RunInDebug || !InIdleThread && !IsTestMode) { IdlePromise.ExecuteOnIdle(cleanup, false); IdlePromise.ExecuteOnIdle(rename, false); } else { cleanup(); rename(); } }
protected override void __eval_internal(FSharpList <Value> args, Dictionary <PortData, Value> outPuts) { var controller = dynRevitSettings.Controller; bool debug = controller.DynamoViewModel.RunInDebug; if (!debug) { #region no debug if ((controller.DynamoViewModel as DynamoRevitViewModel).TransMode == DynamoRevitViewModel.TransactionMode.Manual && !controller.IsTransactionActive()) { throw new Exception("A Revit transaction is required in order evaluate this element."); } controller.InitTransaction(); Evaluate(args, outPuts); foreach (ElementId eid in deletedIds) { controller.RegisterSuccessfulDeleteHook( eid, onSuccessfulDelete ); } deletedIds.Clear(); #endregion } else { #region debug dynSettings.Controller.DynamoViewModel.Log("Starting a debug transaction for element: " + NickName); IdlePromise.ExecuteOnIdle( delegate { controller.InitTransaction(); try { Evaluate(args, outPuts); foreach (ElementId eid in deletedIds) { controller.RegisterSuccessfulDeleteHook( eid, onSuccessfulDelete ); } deletedIds.Clear(); controller.EndTransaction(); ValidateConnections(); } catch (Exception ex) { controller.CancelTransaction(); throw ex; } }, false ); #endregion } #region Register Elements w/ DMU var del = new DynElementUpdateDelegate(onDeleted); foreach (ElementId id in Elements) { controller.RegisterDeleteHook(id, del); } #endregion }