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.