Trapping "Can' keep elements joined" error message.

Trapping "Can' keep elements joined" error message.

sragan
Collaborator Collaborator
407 Views
2 Replies
Message 1 of 3

Trapping "Can' keep elements joined" error message.

sragan
Collaborator
Collaborator

Just for example, if there are two detail lines that are connected, and one is moved in such a way that the other can't stay attached, Revit gives an annoying error message "Can't keep elements joined".  The error message has two options, Unjoin or cancel.   (Actually, there are two other pretty useless options, which I think we can ignore).

This wouldn't be so bad, but the default button is the "Cancel" button (the move command is canceled if Enter is pressed).  In my opinion, "Unjoin" should be the default option and the elements should just disconnect when enter is pressed.  (After all, the user moved one for a reason.)


Is there a way, using the API, to trap that error, and if the user hits "enter", to just unjoin the lines so the user can move on?

 

  

0 Likes
Accepted solutions (1)
408 Views
2 Replies
Replies (2)
Message 2 of 3

so-chong
Advocate
Advocate
Accepted solution

I ran into the same question and experimented a bit with the Revit API failure processing. While you cannot change the default button of the built-in dialog ("Can't keep elements joined"), you can intercept the failure and automatically apply the DetachElements resolution before the dialog appears.

The idea is to hook into the session-wide FailuresProcessing event and resolve the failure programmatically.

Below is a simple Application Macro example that demonstrates the idea. It enables an automatic "unjoin" behavior when the specific failure occurs.

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

namespace [YOUR MODULE NAME]
{
    [Transaction(TransactionMode.Manual)]
    [Autodesk.Revit.DB.Macros.AddInId("2FCC39C0-0068-49F0-82A7-CC1D8706ED63")]
    public partial class ThisApplication
    {
        private bool _autoUnjoinEnabled = false;
        private bool _failureHookAttached = false;

        private void Module_Startup(object sender, EventArgs e)
        {
        }

        private void Module_Shutdown(object sender, EventArgs e)
        {
            DetachFailureHook();
        }
        public void EnableAutoUnjoin()
        {
            AttachFailureHook();
            _autoUnjoinEnabled = true;
            TaskDialog.Show("Auto Unjoin", "Auto-unjoin is ENABLED.");
        }

        public void DisableAutoUnjoin()
        {
            _autoUnjoinEnabled = false;
            TaskDialog.Show("Auto Unjoin", "Auto-unjoin is DISABLED.");
        }

        private void AttachFailureHook()
        {
            if (_failureHookAttached)
                return;

            this.Application.FailuresProcessing += OnFailuresProcessing;
            _failureHookAttached = true;
        }

        private void DetachFailureHook()
        {
            if (!_failureHookAttached)
                return;

            this.Application.FailuresProcessing -= OnFailuresProcessing;
            _failureHookAttached = false;
        }

        private void OnFailuresProcessing(object sender, FailuresProcessingEventArgs e)
        {
            if (!_autoUnjoinEnabled)
                return;

            FailuresAccessor failuresAccessor = e.GetFailuresAccessor();
            IList<FailureMessageAccessor> failures = failuresAccessor.GetFailureMessages();

            bool resolved = false;

            foreach (FailureMessageAccessor failure in failures)
            {
                string description = failure.GetDescriptionText();

                if (string.IsNullOrEmpty(description))
                    continue;

                if (description.IndexOf("Can't keep elements joined", StringComparison.OrdinalIgnoreCase) >= 0)
                {
                    if (failure.HasResolutionOfType(FailureResolutionType.DetachElements))
                    {
                        failure.SetCurrentResolutionType(FailureResolutionType.DetachElements);
                        failuresAccessor.ResolveFailure(failure);
                        resolved = true;
                    }
                }
            }

            if (resolved)
            {
                e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit);
            }
        }
    }
}

Usage in the macro manager:

  • Run EnableAutoUnjoin() to activate the behavior.

  • When the "Can't keep elements joined" failure occurs, the macro automatically applies DetachElements.

  • Run DisableAutoUnjoin() to turn it off again.

Note that this example filters on the failure description text, which works for a quick proof of concept but is language dependent. For a production add-in it would be better to filter using the FailureDefinitionId instead.

Functionally this behaves similar to pressing "Unjoin" automatically, allowing the user operation (e.g. moving a detail line) to continue without the dialog interrupting the workflow.

0 Likes
Message 3 of 3

sragan
Collaborator
Collaborator

Thanks.  That is really helpful.   It works great.

 

 

0 Likes