Trying to suppress the duplicate type prompt, to make it automatically ok with C# anyone?

Trying to suppress the duplicate type prompt, to make it automatically ok with C# anyone?

ed_sa
Enthusiast Enthusiast
1,007 Views
16 Replies
Message 1 of 17

Trying to suppress the duplicate type prompt, to make it automatically ok with C# anyone?

ed_sa
Enthusiast
Enthusiast

Does anyone know how to suppress teh duplicate type prompt when copying draft views from imported file? This below from previous threads didnt work.

 

public MyCopyHandler : IDuplicateTypeNamesHandler
{
   public DuplicateTypeAction OnDuplicateTypeNamesFound()
   {
      return DuplicateTypeAction.UseDestinationTypes;
   }


I tried oterh different things as well. Anyone? thank you
0 Likes
1,008 Views
16 Replies
Replies (16)
Message 2 of 17

jeremy_tammik
Alumni
Alumni

Are you importing a file or using copy and paste? The IDuplicateTypeNamesHandler interface is an interface for custom handlers of duplicate type names encountered during a paste operation:

  

  

Jeremy Tammik Developer Advocacy and Support + The Building Coder + Autodesk Developer Network + ADN Open
0 Likes
Message 3 of 17

ed_sa
Enthusiast
Enthusiast

I've imported a file using : externalDoc = uiApp.Application.OpenDocumentFile(selectedFilePath);
then I  set up a Windows form to choose multiple draft views to be placed onto one sheet on the current document fromt hat outside document .  The code works and it iterates element by element and it takes a while, doesn't seem to be another more efficient, quicker way. I use ElementtransformUtils(doc, viewsheet,view, xyz) to transfer teh elements from one document to another and elementTranfrosmutils for elements into view transfer and finally viewport.create. the problem Im having is this: problem where this: 

public void CopyElementsWithDuplicateTypeHandling(Document importedExternalDoc, ViewDrafting importedSelectedDraftingViews, ICollection<ElementId> elementIds, View targetSheet)
{
// Set the copy paste options to automatically accept duplicate types
CopyPasteOptions options = new CopyPasteOptions();
options.SetDuplicateTypeNamesHandler(new DuplicateTypeHandler());
// Copy elements
ElementTransformUtils.CopyElements(importedSelectedDraftingViews, elementIds, targetSheet, null, options);
} and this: public void CopyElementsWithDuplicateTypeHandling(Document importedExternalDoc, ViewDrafting importedSelectedDraftingViews, ICollection<ElementId> elementIds, View targetSheet)
{
// Set the copy paste options to automatically accept duplicate types
CopyPasteOptions options = new CopyPasteOptions();
options.SetDuplicateTypeNamesHandler(new DuplicateTypeHandler());
// Copy elements
ElementTransformUtils.CopyElements(importedSelectedDraftingViews, elementIds, targetSheet, null, options);
} adn it seems to actually eliminate the duplicate type(just now) but it breaks in visual studio with this message:

You
Managed Debugging Assistant 'ContextSwitchDeadlock' : 'The CLR has been unable to transition from COM context 0x2d4f4168 to COM context 0x2d4f3f18 for 60 seconds. The thread that owns the destination context/apartment is most likely either doing a non pumping wait or processing a very long running operation without pumping Windows messages. This situation generally has a negative performance impact and may even lead to the application becoming non responsive or memory usage accumulating continually over time. To avoid this problem, all single threaded apartment (STA) threads should use pumping wait primitives (such as CoWaitForMultipleHandles) and routinely pump messages during long running operations.'
chatgpt tells me to use asynchronous operations as in Task.Await:

public void CopyElementsWithDuplicateTypeHandling(Document importedExternalDoc, ViewDrafting importedSelectedDraftingViews, ICollection<ElementId> elementIds, View targetSheet)
{
// Start a new transaction
using (Transaction transaction = new Transaction(targetSheet.Document, "Copy Elements"))
{
try
{
// Start the transaction
transaction.Start();

// Perform the copy operation
ElementTransformUtils.CopyElements(importedSelectedDraftingViews, elementIds, targetSheet, null, null);

// Commit the transaction
transaction.Commit();
}
catch (Exception ex)
{
// If an exception occurs, rollback the transaction
transaction.RollBack();
TaskDialog.Show("Error", $"Failed to copy elements: {ex.Message}");
}
}
} but I haven't tried that.  Any takes?

0 Likes
Message 4 of 17

ed_sa
Enthusiast
Enthusiast

here's short version. this method:

public class DuplicateTypeHandler : IDuplicateTypeNamesHandler
{
public DuplicateTypeAction OnDuplicateTypeNamesFound(DuplicateTypeNamesHandlerArgs args)
{
return DuplicateTypeAction.UseDestinationTypes; // Always accept duplicate types

//public enum DuplicateTypeAction
//{
// Accept,
// Cancel
//}

}

} works to substitute the element import to current doc and delete altogether. but  it will still show the very first Duplicate type taskdialog message at the beginning of each draft view iteration beginning. Im trying to see if I can elimiante that too.  Also there is a question in the very end about whether we want to rename a draftview, how can we eliminate that as well? Thank you. 

0 Likes
Message 5 of 17

ctm_mka
Collaborator
Collaborator

ed, try a failure handler to suppress the warning, like so:

private void HideDupeMessages(object sender, FailuresProcessingEventArgs e)
{
   FailuresAccessor FA = e.GetFailuresAccessor();
   foreach (FailureMessageAccessor fmsg in FA.GetFailureMessages())
   {
       if (fmsg.GetSeverity() == FailureSeverity.Warning)
       {
          FA.DeleteWarning(fmsg);
          e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit);
        }
        if (fmsg.GetSeverity() == FailureSeverity.Error)
        {
          FA.ResolveFailure(fmsg);
          e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit);
         }
    }
    e.SetProcessingResult(FailureProcessingResult.Continue);
 }
0 Likes
Message 6 of 17

ed_sa
Enthusiast
Enthusiast

failure for what exactly? .CopyElements?

0 Likes
Message 7 of 17

ctm_mka
Collaborator
Collaborator

Yes. Its not actually a failure, but that event handler catches it where the duplicate names handler does not. Plus it handles actual errors, which i care nothing about (I forget what they are, but they are repeatable and happen every time), you could remove that part.

0 Likes
Message 8 of 17

ed_sa
Enthusiast
Enthusiast

so somewhere before  DuplicateTypeAction.UseDestinationTypes;  ?

0 Likes
Message 9 of 17

ed_sa
Enthusiast
Enthusiast

nevermind, I misread. for copyelements you confirmed

0 Likes
Message 10 of 17

ed_sa
Enthusiast
Enthusiast

that didn't work. Thank you for trying.

0 Likes
Message 11 of 17

ctm_mka
Collaborator
Collaborator

ed, how did you try and implement it? Im assuming you are doing this for multiple views? you will need to register the event handler, preferably before whatever loop you are calling your "CopyElementsWithDuplicateTypeHandling" method from.

0 Likes
Message 12 of 17

ed_sa
Enthusiast
Enthusiast

I didn't use an event handler.  I was considering using Parallel.foreach for each draftingview iterated element id, I don't know if that's possible.  Here is themethod with this involved: 

private ViewSheet PlaceDraftingViewOnSheet(Document currentDoc, List<ViewDrafting> importedSelectedDraftingViews, EfficientSelectDraftingViewFormFinalMultipleATTEMPT viewForm, ViewSheet importedSelectedSheet)
{
ICollection<Element> draftingViewElements = null;
// Check if the required parameters are null
if (currentDoc == null || importedSelectedDraftingViews == null || viewForm == null || importedSelectedSheet == null)
{
TaskDialog.Show("Error", "One or more required parameters is null(twelve)");
return null;
}
if (!(importedSelectedDraftingViews is List<ViewDrafting>))
{
TaskDialog.Show("Error", "The selected view is not a drafting view");
return null;
}

//Check if selectedDraftingViews contains any elements
foreach (ViewDrafting viewD in importedSelectedDraftingViews)
{
FilteredElementCollector collector = new FilteredElementCollector(viewD.Document, viewD.Id);
draftingViewElements = collector//ICollection<Element>
.WhereElementIsNotElementType()
.ToElements();

if (draftingViewElements.Count == 0 || draftingViewElements == null)
{
TaskDialog.Show("Info", "The selected drafting view does not contain any elements.");
return null;
}
//Loop through each element in each draftingView.
foreach (Element element in draftingViewElements)
{
if (element == null)
{
//if (importedSelectedSheet == null || selectedDraftingViews == null || draftingViewElements == null)
//{
TaskDialog.Show("Error", $"Selected sheet '{importedSelectedSheet.Name}' not found(thirteen)");
return null;
//}
}
}
}

try
{
double offsetX = 0.0;//Initial X Offset
double offsetY = 0.0;// Y Offset

foreach (ViewDrafting importedSelectedDraftingView in importedSelectedDraftingViews)
{
if (importedSelectedDraftingView != null && externalDoc != null && currentDoc != null)
{

//ICollection<ElementId> CopiedElements = ElementTransformUtils.CopyElements(externalDoc, new List<ElementId> { selectedDraftingView.Id }, currentDoc, null, null);
// Copy the drafting view to the current document
ElementId copiedViewElementId = ElementTransformUtils.CopyElements(externalDoc, new List<ElementId> { importedSelectedDraftingView.Id }, currentDoc, null, null).FirstOrDefault();

if (copiedViewElementId == null || copiedViewElementId == ElementId.InvalidElementId)
{
TaskDialog.Show("Error", "Failed to copy the drafting view to the sheet");
return null;
}
// Store the copied view element ID for later use
copiedViewElementIds.Add(copiedViewElementId);


View copyView = currentDoc.GetElement(copiedViewElementId) as View;
// Validate the sheet and drafting view dimensions
if (importedSelectedSheet != null && importedSelectedDraftingView != null)
{
if (!ValidateSheetAndDraftingView(importedSelectedSheet, importedSelectedDraftingView))
{
return null; // Validation failed
}
}

IEnumerable<ElementId> vft = new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id)
.Where(e =>
(e.Category != null && !(e is View)))
.Select(e => e.Id);


IEnumerable<ElementId> draftViewsInView = new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id)
.OfClass(typeof(ViewDrafting))
.Select(e => e.Id);

IEnumerable<ElementId> detailLinesInView = new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id)
//.OfClass(typeof(DetailLine))
.OfClass(typeof(CurveElement))
//.Where(e => e is DetailLine)
.Select(e => e.Id);

IEnumerable<ElementId> familyInstancesInView = new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id)
.OfClass(typeof(FamilyInstance))
.WhereElementIsNotElementType()
.Cast<FamilyInstance>()
.Where(fi => fi.Category.Name == "Views")
.Select(fi => fi.Id);
//.OfCategory(BuiltInCategory.OST_TextNotes)
//.OfCategory(BuiltInCategory.OST_GenericAnnotation)
//.Union(new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id).OfCategory(BuiltInCategory.OST_Dimensions))
//.Union(new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id).OfCategory(BuiltInCategory.OST_GenericAnnotation))
//.Select(e => e.Id);

//.ToList();

//Filtered Element collector for detail components within the specified view
IEnumerable<ElementId> detailComponentsInView = new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id)
.OfCategory(BuiltInCategory.OST_DetailComponents)
.Where(e => (e is Autodesk.Revit.DB.Group))
.Select(e => e.Id);
//.ToList();

//Filtered Element collector for sketch elements within the specified view
IEnumerable<ElementId> sketchElementsInView = new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id)
.OfClass(typeof(CurveElement))
//.Where(e => e is Sketch || e is ModelCurve || e is DetailCurve || e is FilledRegion)
.Select(e => e.Id);
//.ToList();

//Filtered Element Collector for view filters within the specified view
IEnumerable<ElementId> viewFiltersInView = new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id)
.OfClass(typeof(ParameterFilterElement))
.Select(e => e.Id);
//.ToList();

//Filtered Element Collector for imported CAD files within the specified view
IEnumerable<ElementId> importedCADFilesInView = new FilteredElementCollector(externalDoc, importedSelectedDraftingView.Id)
.OfClass(typeof(ImportInstance))
.Select(e => e.Id);
//.ToList();

List<ElementId> nonExportableElementsInView = importedCADFilesInView.ToList();

//--------------------------------------------------------------------------------------------------
//---------------------------------------------------------------------------------------------------------------------------
vft = vft.Except(nonExportableElementsInView);
//Test print all elements by name and Id(KEEP CODE)
// Check if all elements were successfully copied
if (copiedViewElementIds.Count < vft.Count())
{
//TaskDialog.Show("Error", "Some elements could not be copied:");
}

//Version Efficient-OLD
//foreach (ElementId elementId in vft)
//{
// if (!copiedViewElementIds.Contains(elementId))
// {
// Element elementToCopy = externalDoc.GetElement(elementId);
// if (elementToCopy != null &&
// //!IsAnnotationComponent(elementToCopy) &&
// //!IsDetailComponent(elementToCopy) &&
// //!IsTemporaryOrAuxiliaryGeometry(elementToCopy) &&
// !IsView(elementToCopy) &&
// //!IsLine(elementToCopy) &&
// //!IsDimension(elementToCopy) &&
// !IsRevitDBCategory(elementToCopy) &&
// !IsCategoryNameViews(elementToCopy))
// {
// try
// {
// if (IsDetailGroup(elementToCopy))
// {
// // If the element is a detail group, extract its elements and copy them individually
// Group detailGroup = elementToCopy as Group;
// ICollection<ElementId> groupMemberIds = detailGroup.GetMemberIds();
// foreach (ElementId memberId in groupMemberIds)
// {
// Element memberToCopy = externalDoc.GetElement(memberId);
// if (memberToCopy != null)
// //!IsAnnotationComponent(memberToCopy) &&
// //!IsDetailComponent(memberToCopy) &&
// //!IsTemporaryOrAuxiliaryGeometry(memberToCopy) &&
// //!IsView(memberToCopy) &&
// //!IsLine(memberToCopy) &&
// //!IsDimension(memberToCopy) &&
// //!IsRevitDBCategory(memberToCopy) &&
// //!IsCategoryNameViews(memberToCopy))
// {
// // Copy the individual member
// //ElementTransformUtils.CopyElements(importedSelectedDraftingView, new List<ElementId> { memberId }, copyView, Transform.Identity, null);
// //
// CopyElementsWithDuplicateTypeHandling(externalDoc, importedSelectedDraftingView, new List<ElementId> { memberId }, copyView);
// // If the copy operation succeeds, add the element to the list of copied elements
// copiedViewElementIds.Add(memberId);
// }
// }
// }
// else
// {
// // If the element is not a detail group, copy it as usual
// //ElementTransformUtils.CopyElements(importedSelectedDraftingView, new List<ElementId> {elementId} , copyView, Transform.Identity, null);

// CopyElementsWithDuplicateTypeHandling(externalDoc, importedSelectedDraftingView, new List<ElementId> { elementId }, copyView);
// // If the copy operation succeeds, add the element to the list of copied elements
// copiedViewElementIds.Add(elementId);
// }
// }
// catch (Exception ex)
// {
// // Construct the error message
// string errorMessage = $"Failed to copy Element: {ex.Message} - Element Name: {elementToCopy.Name}, Category: {elementToCopy.Category?.Name ?? "Uncategorized"}, ID: {elementToCopy.Id.IntegerValue}";
// // Display the error message
// TaskDialog.Show("Error", errorMessage);
// }
// }
// }
//}
HashSet<ElementId> copiedElementIdsSet = new HashSet<ElementId>(copiedViewElementIds);

var elementsToCopy = vft.Except(copiedElementIdsSet)
.Select(elementId => externalDoc.GetElement(elementId))
.Where(elementToCopy =>
elementToCopy != null &&
!IsView(elementToCopy) &&
!IsRevitDBCategory(elementToCopy) &&
!IsCategoryNameViews(elementToCopy));

foreach (Element elementToCopy in elementsToCopy)
{
if (IsDetailGroup(elementToCopy))
{
Autodesk.Revit.DB.Group detailGroup = elementToCopy as Autodesk.Revit.DB.
Group;
ICollection<ElementId> groupMemberIds = detailGroup.GetMemberIds();
foreach (ElementId memberId in groupMemberIds)
{
Element memberToCopy = externalDoc.GetElement(memberId);
if (memberToCopy != null &&
!IsView(memberToCopy) &&
!IsRevitDBCategory(memberToCopy) &&
!IsCategoryNameViews(memberToCopy))
{
CopyElementsWithDuplicateTypeHandling(externalDoc, importedSelectedDraftingView, new List<ElementId> { memberId }, copyView);
copiedElementIdsSet.Add(memberId);
}
}
}
else
{
CopyElementsWithDuplicateTypeHandling(externalDoc, importedSelectedDraftingView, new List<ElementId> { elementToCopy.Id }, copyView);
copiedElementIdsSet.Add(elementToCopy.Id);
}
}

 

//^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
// Get the copied drafting view element

if (copyView != null && copyView is View copiedView)
{
//XYZ sheetCenter = CalculateSheetCenter(newSheet);
XYZ sheetCenter = CalculateSheetCenter(importedSelectedSheet);
//TaskDialog.Show("Print", $"importedSelectedSheet variable{importedSelectedSheet}");
//XYZ viewportPosition = new XYZ(sheetCenter.X + offsetX, sheetCenter.Y + offsetY, sheetCenter.Z);

//Viewport viewport = Viewport.Create(currentDoc, newSheet.Id, copiedView.Id, sheetCenter);
Viewport viewport = Viewport.Create(currentDoc, importedSelectedSheet.Id, copiedView.Id, sheetCenter);
currentDoc.Regenerate();
if (viewport == null)
{
TaskDialog.Show("Error", "Failed to create viewport for the drafting view in the sheet(fourteen) !");
return null;
}
offsetX += 100.0;
offsetY += 0.0;
}
else
{
TaskDialog.Show("Error", "Error past the try before returning selected Sheet");
return null;
}
}
else
{
TaskDialog.Show("Print", "Selected Drafting View is null");
}
}
return importedSelectedSheet;
}
catch (Exception ex)
{
TaskDialog.Show("Error", $"An error occurred(seventeen): {ex.Message}");
return null;
}
}
private void HideDupeMessages(object sender, FailuresProcessingEventArgs e)
{
FailuresAccessor FA = e.GetFailuresAccessor();
foreach (FailureMessageAccessor fmsg in FA.GetFailureMessages())
{
if (fmsg.GetSeverity() == FailureSeverity.Warning && IsDuplicateTypeMessage(fmsg))
{
// Always delete the warning and proceed with the operation
FA.DeleteWarning(fmsg);
e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit);
}
}
// Continue with the operation for other failure messages
//e.SetProcessingResult(FailureProcessingResult.ProceedWithCommit);
e.SetProcessingResult(FailureProcessingResult.Continue);
}

0 Likes
Message 13 of 17

ed_sa
Enthusiast
Enthusiast

I think you're mistaken.  There is no event handler.  I call teh method and then run the foreach loop iwth copyelements in it. Maybe on your code you have to register for an event handler. I believe that'd be an entirely different code.

0 Likes
Message 14 of 17

ed_sa
Enthusiast
Enthusiast

here's teh other method:  public void CopyElementsWithDuplicateTypeHandling(Document importedExternalDoc, ViewDrafting importedSelectedDraftingViews, ICollection<ElementId> elementIds, View targetSheet)
{
// Set the copy paste options to automatically accept duplicate types
CopyPasteOptions options = new CopyPasteOptions();
options.SetDuplicateTypeNamesHandler(new DuplicateTypeHandlerATTEMPT());

// Copy elements
ElementTransformUtils.CopyElements(importedSelectedDraftingViews, elementIds, targetSheet, null, options);
}

0 Likes
Message 15 of 17

ctm_mka
Collaborator
Collaborator

ed, to use the code i posted with your code, you need to register it in your code, probably best done at the very beginning of your program:

ExternalCommandData.Application.Application.FailuresProcessing += HideDupeMessages;

 

0 Likes
Message 16 of 17

ed_sa
Enthusiast
Enthusiast

ok just Ill just copy your register code and test it, will let you know.thank you. 🙂

0 Likes
Message 17 of 17

ed_sa
Enthusiast
Enthusiast

wasn't compatible.  I will try something else later and let you know. Thanks again.

0 Likes