Hi, thanks for the reply,
I've tried the macro in your previous attachment
but looks like it was merely a listing tool instead of modifying the document...
and I've tried follow your suggestion to call a functionality from a ExternalEventHandler class,
but still didn't work..
either had no response at all in DoWork Event,

or gotten an error msg in Completed Event:

my current achievable way is by using Transaction inside function itself before Executed when a DoWork Event Triggered,
but it will create tons of undo-history because each list item will have its own handling session...
is it possible to concludes those Transactions into a TransactionGroup before Initialize BackgroundWorker?
Thanks in advance :]
Here is the entire code block:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Threading;
using System.Windows.Controls;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;
using System.Linq;
using System.Collections;
namespace DLN_AddinV2
{
[Transaction(TransactionMode.Manual)]
internal class DeleteWallsInBackgroundCommand : IExternalCommand
{
public Document _Doc1;
public List<ElementId> _List1 = new List<ElementId>();
private ExternalEvent externalEvent;
private ExternalEventHandler externalEventHandler;
public Result Execute( ExternalCommandData commandData, ref string message, ElementSet elements)
{
try
{
UIApplication app1 = commandData.Application;
Document doc1 = app1.ActiveUIDocument.Document;
_Doc1 = doc1;
// Initialize ExternalEvent and ExternalEventHandler
externalEventHandler = new ExternalEventHandler(commandData);
externalEvent = ExternalEvent.Create(externalEventHandler);
// Initialize BackgroundWorker
BackgroundWorker backgroundWorker = new BackgroundWorker();
backgroundWorker.DoWork += BackgroundWorker_DoWork;
backgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted;
// Start BackgroundWorker
backgroundWorker.RunWorkerAsync();
return Result.Succeeded;
}
catch (Exception ex)
{
message = ex.Message;
TaskDialog.Show("catch", message);
return Result.Failed;
}
}
private void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
_List1 = C0_GetData.GetAllElementsAll(_Doc1).Where(x => _Doc1.GetElement(x).Category.Name.Contains("Wall")).ToList();
// Perform background work (e.g., simulation)
try
{
for (int i = 0; i < _List1.Count(); i++)
{
// Simulate work being done
Thread.Sleep(100);
try
{
externalEventHandler._Id1 = _List1[i];
}
catch (Exception ex) { TaskDialog.Show("catch", ex.Message); }
// Report progress to the main thread using ExternalEvent
externalEvent.Raise();
}
}
catch (Exception ex) { TaskDialog.Show("catch", ex.Message); }
/* Cannot open a Transaction session before called function or it won't work
using (Transaction transaction = new Transaction(_Doc1, "DeleteWallsTransaction"))
{
transaction.Start();
externalEventHandler.DeleteWallByID(_Doc1, externalEventHandler._Id1);
transaction.Commit();
}
*/
}
private void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
// BackgroundWorker completed
externalEvent.Dispose(); // Dispose of ExternalEvent
}
}
public class ExternalEventHandler : IExternalEventHandler
{
public ExternalCommandData CommandData { get; private set; }
public ElementId _Id1 { get; set; }
public ExternalEventHandler(ExternalCommandData commandData)
{
CommandData = commandData;
}
public void Execute(UIApplication app)
{
// Code to execute on the main thread
// Update UI or perform Revit API operations
DeleteWallByID(app.ActiveUIDocument.Document, _Id1);
}
public string GetName()
{
return "ExternalEventHandler";
}
public void DeleteWallByID(Document doc1, ElementId id1)
{
// the Transaction session needs to be used inside the function or it won't work
using (Transaction transaction = new Transaction(doc1, "DeleteWallsTransaction"))
{
transaction.Start();
// Call the method to delete all walls in the view
doc1.Delete(id1);
transaction.Commit();
}
}
}
}