Revit API Forum
Welcome to Autodesk’s Revit API Forums. Share your knowledge, ask questions, and explore popular Revit API topics.
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Issue with DialogBoxShowingEvents

2 REPLIES 2
SOLVED
Reply
Message 1 of 3
ctm_mka
229 Views, 2 Replies

Issue with DialogBoxShowingEvents

ctm_mka
Advocate
Advocate

Revit 2023. Attempting to batch join wall and floors, using "DialogBoxShowingEventArgs" to suppress this warning by setting the override result to commandlink1, or unjoin elements.

ctm_mka_0-1721420537808.png

the code thus far:

 

namespace Batch_Switch_Join_Order
{
    [Transaction(TransactionMode.Manual)]
    public class BatchSwitcherooo : IExternalCommand
    {
        public Result Execute(ExternalCommandData commdata, ref string msg, ElementSet elemset)
        {
            UIApplication _uiapp = commdata.Application;
            UIDocument _uidoc = commdata.Application.ActiveUIDocument;
            Document _doc = _uidoc.Document;
            _uiapp.DialogBoxShowing += new EventHandler<DialogBoxShowingEventArgs>(Dialogboxshower);
            List<Element> walls = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToList();
            List<Element> floors = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_Floors).WhereElementIsNotElementType().ToList();
            using (TransactionGroup trg = new TransactionGroup(_doc))
            {
                trg.Start("theJoining");
                foreach (Element wall in walls)
                {
                    foreach (Element floor in floors)
                    {
                        using (Transaction tr = new Transaction(_doc))
                        {
                            tr.Start("Joining");
                            try
                            {
                                JoinGeometryUtils.JoinGeometry(_doc, wall, floor);
                                //JoinGeometryUtils.SwitchJoinOrder(_doc, wall, floor);
                                tr.Commit();
                            }
                            catch
                            {
                                tr.RollBack();
                            }
                        }
                    }

                }
                trg.Assimilate();
            }
            return Result.Succeeded;
        }

        private void Dialogboxshower(object sender, DialogBoxShowingEventArgs e)
        {
            string s = e.DialogId.ToString();
            if (e.DialogId.Equals("Dialog_Revit_DocWarnDialog"))
            {
                e.OverrideResult((int)TaskDialogResult.CommandLink1);
            }

        }
    }
}

 

Now, this is working fine, however, theres a nasty "regen flicker" each time, see attached GIF. Ive tried getting at it as a TaskDialog and MessageDialog, both return null. FailureProcessor registers it, but FailuresAccessor.GetFailureMessages() returns empty, so nothing more i could do with that. Could be with how im structuring the nested transactions/for loops? Thoughts?

0 Likes

Issue with DialogBoxShowingEvents

Revit 2023. Attempting to batch join wall and floors, using "DialogBoxShowingEventArgs" to suppress this warning by setting the override result to commandlink1, or unjoin elements.

ctm_mka_0-1721420537808.png

the code thus far:

 

namespace Batch_Switch_Join_Order
{
    [Transaction(TransactionMode.Manual)]
    public class BatchSwitcherooo : IExternalCommand
    {
        public Result Execute(ExternalCommandData commdata, ref string msg, ElementSet elemset)
        {
            UIApplication _uiapp = commdata.Application;
            UIDocument _uidoc = commdata.Application.ActiveUIDocument;
            Document _doc = _uidoc.Document;
            _uiapp.DialogBoxShowing += new EventHandler<DialogBoxShowingEventArgs>(Dialogboxshower);
            List<Element> walls = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToList();
            List<Element> floors = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_Floors).WhereElementIsNotElementType().ToList();
            using (TransactionGroup trg = new TransactionGroup(_doc))
            {
                trg.Start("theJoining");
                foreach (Element wall in walls)
                {
                    foreach (Element floor in floors)
                    {
                        using (Transaction tr = new Transaction(_doc))
                        {
                            tr.Start("Joining");
                            try
                            {
                                JoinGeometryUtils.JoinGeometry(_doc, wall, floor);
                                //JoinGeometryUtils.SwitchJoinOrder(_doc, wall, floor);
                                tr.Commit();
                            }
                            catch
                            {
                                tr.RollBack();
                            }
                        }
                    }

                }
                trg.Assimilate();
            }
            return Result.Succeeded;
        }

        private void Dialogboxshower(object sender, DialogBoxShowingEventArgs e)
        {
            string s = e.DialogId.ToString();
            if (e.DialogId.Equals("Dialog_Revit_DocWarnDialog"))
            {
                e.OverrideResult((int)TaskDialogResult.CommandLink1);
            }

        }
    }
}

 

Now, this is working fine, however, theres a nasty "regen flicker" each time, see attached GIF. Ive tried getting at it as a TaskDialog and MessageDialog, both return null. FailureProcessor registers it, but FailuresAccessor.GetFailureMessages() returns empty, so nothing more i could do with that. Could be with how im structuring the nested transactions/for loops? Thoughts?

2 REPLIES 2
Message 2 of 3
Moustafa_K
in reply to: ctm_mka

Moustafa_K
Collaborator
Collaborator
Accepted solution

the DialogBoxShowingEventArgs is triggered when the dialog is about to be shown, and not to hold the showing process. depending on the speed of the GPU and the processor the flicker might be expected.

 

I am using different implementation to avoid such window flicker using the IFailuresPreprocessor Handler. the implementation is straight forward. see the example already there in the documentation. in your case the failure IDs would be one of these 2 Ids, or may be both.

BuiltInFailures.JoinElementsFailures.JoiningDisjointWarn,
BuiltInFailures.JoinElementsFailures.JoiningDisjoint,

 

You can add these failure process to the Transaction. see this implementation:

public void JoinElements(Element e1, Element e2)
{ 
    var trans = new Transaction(e1.Document, "Join");
    var failop = trans.GetFailureHandlingOptions();
    failop.SetFailuresPreprocessor(new JoinWarningSwallower());
    trans.SetFailureHandlingOptions(failop);

    trans.Start();
    JoinGeometryUtils.JoinGeometry(Doc, e1, e2);
    trans.Commit();
}

public class JoinWarningSwallower : IFailuresPreprocessor
{
    public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
    {
        IList<FailureMessageAccessor> failList = new List<FailureMessageAccessor>();
        // Inside event handler, get all warnings
        failList = failuresAccessor.GetFailureMessages();
        foreach (FailureMessageAccessor failure in failList)
        {
            // check FailureDefinitionIds against ones that you want to dismiss,
            FailureDefinitionId failID = failure.GetFailureDefinitionId();

            // prevent Revit from showing Unenclosed room warnings you can ignore the if so,
            // it can delete any warning occurs, if you are sure
            // you know what are you are doing.
            if (
                failID == BuiltInFailures.JoinElementsFailures.JoiningDisjoint
                || failID == BuiltInFailures.JoinElementsFailures.JoiningDisjointWarn
            )
            {
                failuresAccessor.DeleteWarning(failure);
            }
        }

        return FailureProcessingResult.Continue;
    }
}

 

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
0 Likes

the DialogBoxShowingEventArgs is triggered when the dialog is about to be shown, and not to hold the showing process. depending on the speed of the GPU and the processor the flicker might be expected.

 

I am using different implementation to avoid such window flicker using the IFailuresPreprocessor Handler. the implementation is straight forward. see the example already there in the documentation. in your case the failure IDs would be one of these 2 Ids, or may be both.

BuiltInFailures.JoinElementsFailures.JoiningDisjointWarn,
BuiltInFailures.JoinElementsFailures.JoiningDisjoint,

 

You can add these failure process to the Transaction. see this implementation:

public void JoinElements(Element e1, Element e2)
{ 
    var trans = new Transaction(e1.Document, "Join");
    var failop = trans.GetFailureHandlingOptions();
    failop.SetFailuresPreprocessor(new JoinWarningSwallower());
    trans.SetFailureHandlingOptions(failop);

    trans.Start();
    JoinGeometryUtils.JoinGeometry(Doc, e1, e2);
    trans.Commit();
}

public class JoinWarningSwallower : IFailuresPreprocessor
{
    public FailureProcessingResult PreprocessFailures(FailuresAccessor failuresAccessor)
    {
        IList<FailureMessageAccessor> failList = new List<FailureMessageAccessor>();
        // Inside event handler, get all warnings
        failList = failuresAccessor.GetFailureMessages();
        foreach (FailureMessageAccessor failure in failList)
        {
            // check FailureDefinitionIds against ones that you want to dismiss,
            FailureDefinitionId failID = failure.GetFailureDefinitionId();

            // prevent Revit from showing Unenclosed room warnings you can ignore the if so,
            // it can delete any warning occurs, if you are sure
            // you know what are you are doing.
            if (
                failID == BuiltInFailures.JoinElementsFailures.JoiningDisjoint
                || failID == BuiltInFailures.JoinElementsFailures.JoiningDisjointWarn
            )
            {
                failuresAccessor.DeleteWarning(failure);
            }
        }

        return FailureProcessingResult.Continue;
    }
}

 

Moustafa Khalil
Cropped-Sharp-Bim-500x125-Autodesk-1
Message 3 of 3
ctm_mka
in reply to: ctm_mka

ctm_mka
Advocate
Advocate

@Moustafa_Kyup that did the trick, thanks. In summation, for the curious:  Implementing IFailuresPreProcessor, and attaching it to the transaction, rather than FailuresProcceingEventArgs as an event handler is the solution.

Revised code attached, i had to nuke the Try/Catch as it was saying the transaction had not started yet:

 

using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace Batch_Switch_Join_Order
{
    [Regeneration(RegenerationOption.Manual)]
    public class BatchSwitcherooo : IExternalCommand
    {
        public Result Execute(ExternalCommandData commdata, ref string msg, ElementSet elemset)
        {
            UIApplication _uiapp = commdata.Application;
            UIDocument _uidoc = commdata.Application.ActiveUIDocument;
            Document _doc = _uidoc.Document;
            List<Element> walls = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToList();
            List<Element> floors = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_Floors).WhereElementIsNotElementType().ToList();
            using (TransactionGroup trg = new TransactionGroup(_doc))
            {
                trg.Start("theJoining");
                foreach (Element wall in walls)
                {
                    using (Transaction tr = new Transaction(_doc))
                    {
                        var failop = tr.GetFailureHandlingOptions();
                        failop.SetFailuresPreprocessor(new FailSauce());
                        tr.SetFailureHandlingOptions(failop);
                        tr.Start("Joining");
                        foreach (Element floor in floors)
                        {
                            JoinGeometryUtils.JoinGeometry(_doc, wall, floor);
                            JoinGeometryUtils.SwitchJoinOrder(_doc, wall, floor);
                        }
                        tr.Commit();
                    }
                }
                trg.Assimilate();
            }
            return Result.Succeeded;
        }
    }
    public class FailSauce : IFailuresPreprocessor
    {
        public FailureProcessingResult PreprocessFailures(FailuresAccessor failaccess)
        {
            foreach (FailureMessageAccessor failmsg in failaccess.GetFailureMessages())
            {
                FailureDefinitionId failid = failmsg.GetFailureDefinitionId();
                if (failid == BuiltInFailures.JoinElementsFailures.JoiningDisjoint ^ failid == BuiltInFailures.JoinElementsFailures.JoiningDisjointWarn)
                {
                    failaccess.DeleteWarning(failmsg);
                }
            }
            return FailureProcessingResult.Continue;
        }
    }
}

 

0 Likes

@Moustafa_Kyup that did the trick, thanks. In summation, for the curious:  Implementing IFailuresPreProcessor, and attaching it to the transaction, rather than FailuresProcceingEventArgs as an event handler is the solution.

Revised code attached, i had to nuke the Try/Catch as it was saying the transaction had not started yet:

 

using System.Collections.Generic;
using System.Linq;
using Autodesk.Revit.Attributes;
using Autodesk.Revit.DB;
using Autodesk.Revit.UI;

namespace Batch_Switch_Join_Order
{
    [Regeneration(RegenerationOption.Manual)]
    public class BatchSwitcherooo : IExternalCommand
    {
        public Result Execute(ExternalCommandData commdata, ref string msg, ElementSet elemset)
        {
            UIApplication _uiapp = commdata.Application;
            UIDocument _uidoc = commdata.Application.ActiveUIDocument;
            Document _doc = _uidoc.Document;
            List<Element> walls = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_Walls).WhereElementIsNotElementType().ToList();
            List<Element> floors = new FilteredElementCollector(_doc).OfCategory(BuiltInCategory.OST_Floors).WhereElementIsNotElementType().ToList();
            using (TransactionGroup trg = new TransactionGroup(_doc))
            {
                trg.Start("theJoining");
                foreach (Element wall in walls)
                {
                    using (Transaction tr = new Transaction(_doc))
                    {
                        var failop = tr.GetFailureHandlingOptions();
                        failop.SetFailuresPreprocessor(new FailSauce());
                        tr.SetFailureHandlingOptions(failop);
                        tr.Start("Joining");
                        foreach (Element floor in floors)
                        {
                            JoinGeometryUtils.JoinGeometry(_doc, wall, floor);
                            JoinGeometryUtils.SwitchJoinOrder(_doc, wall, floor);
                        }
                        tr.Commit();
                    }
                }
                trg.Assimilate();
            }
            return Result.Succeeded;
        }
    }
    public class FailSauce : IFailuresPreprocessor
    {
        public FailureProcessingResult PreprocessFailures(FailuresAccessor failaccess)
        {
            foreach (FailureMessageAccessor failmsg in failaccess.GetFailureMessages())
            {
                FailureDefinitionId failid = failmsg.GetFailureDefinitionId();
                if (failid == BuiltInFailures.JoinElementsFailures.JoiningDisjoint ^ failid == BuiltInFailures.JoinElementsFailures.JoiningDisjointWarn)
                {
                    failaccess.DeleteWarning(failmsg);
                }
            }
            return FailureProcessingResult.Continue;
        }
    }
}

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk Design & Make Report