I have this code below. Viewport.Create it's returning null in code below. Can anyone tell me why? (I used .Duplicate method for a drafting view which worked-includes all elements supposedly)

I have this code below. Viewport.Create it's returning null in code below. Can anyone tell me why? (I used .Duplicate method for a drafting view which worked-includes all elements supposedly)

ed_sa
Enthusiast Enthusiast
462 Views
2 Replies
Message 1 of 3

I have this code below. Viewport.Create it's returning null in code below. Can anyone tell me why? (I used .Duplicate method for a drafting view which worked-includes all elements supposedly)

ed_sa
Enthusiast
Enthusiast
using (Autodesk.Revit.DB.Transaction transaction = new Autodesk.Revit.DB.Transaction(currentDoc, "Transaction for all"))
{
try
{
transaction.Start();
// Iterate through each drafting view in the external document
foreach (ViewDrafting selectedDraftingView in selectedDraftingViews)
{
if (selectedDraftingView != null)
{
// Check if the drafting view is valid
if (!selectedDraftingView.IsValidObject)
{
TaskDialog.Show("Error", "The selected drafting view is invalid.");
transaction.RollBack();
return Result.Failed;
}
ElementId blockId;
// Duplicate the drafting view
using (Transaction externalTransaction = new Transaction(externalDoc, "ExternalDoc"))
{
externalTransaction.Start();
blockId = selectedDraftingView.Duplicate(ViewDuplicateOption.Duplicate);
externalTransaction.Commit();
}

if (blockId == null || blockId == ElementId.InvalidElementId)
{
TaskDialog.Show("Error", "Failed to duplicate the drafting view.");
transaction.RollBack();
return Result.Failed;
}

// Get the duplicated block element
Element block = externalDoc.GetElement(blockId);
if (block == null)
{
TaskDialog.Show("Error", "Failed to retrieve the duplicated drafting view.");
transaction.RollBack();
return Result.Failed;
}

// Create a viewport for the duplicated drafting view
Viewport viewport = Viewport.Create(currentDoc, selectedSheet.Id, blockId, XYZ.Zero);
if (viewport == null)
{
TaskDialog.Show("Error", "Failed to create viewport for the drafting view.");
transaction.RollBack();
return Result.Failed;
}
}
}
transaction.Commit();
externalDoc.Close(false);
return Result.Succeeded;
}
catch(Exception ex)
{
TaskDialog.Show("Error", $"{ex.Message}");
return Result.Failed;
}
}
}
0 Likes
Accepted solutions (1)
463 Views
2 Replies
Replies (2)
Message 2 of 3

ed_sa
Enthusiast
Enthusiast

Im actually going to attempt to answer based on a chatgpt answer I also paste below. Apparently, even though the transaction where Viewport.Create is run inside the current docuemtn transaction, since you're using an external reference in blockId with the duplicate method, all you have to do, is use 'externalDoc' instead of currentDoc because the source document where the blockId is coming from. I can't test it, but it's up to other users to do so, may or may not work. This is chat gpt answer:

 

In the provided code, the Viewport.Create method is indeed being called within the scope of a transaction. However, there's a potential issue in how the transactions are nested.

Here's a breakdown of the transaction handling:

  1. The outer transaction (transaction) is created with the current document (currentDoc) as its context. This transaction wraps the entire process of duplicating drafting views and creating viewports.

  2. Inside the loop, a separate transaction (externalTransaction) is started using the external document (externalDoc) as its context. This transaction is used for duplicating drafting views from the external document.

  3. Within the loop, after duplicating the drafting view, the Viewport.Create method is called using currentDoc as the first argument. This suggests that the viewport is being created in the current document.

Now, the potential issue lies in using the externalDoc for duplicating views and then attempting to create a viewport in the currentDoc. This might lead to problems because the viewport is being created in a different document than the one where the drafting view was duplicated from.

To address this potential issue, you should ensure that the viewport is created in the same document where the drafting view was duplicated. Therefore, you should pass externalDoc instead of currentDoc as the first argument to Viewport.Create:

 

csharpCopy code
Viewport viewport = Viewport.Create(externalDoc, selectedSheet.Id, blockId, XYZ.Zero);
 

By doing this, you ensure that the viewport is created in the correct document, which should resolve the issue of getting null for the viewport.

Additionally, you may want to consider a more granular approach to handling transactions. For instance, you could start and commit transactions for each viewport creation individually rather than wrapping the entire process in a single transaction. This can help isolate potential issues and make the code more robust.

This would be the change in code:

 

// Create a viewport for the duplicated drafting view
//Not this!
Viewport viewport = Viewport.Create(currentDoc, selectedSheet.Id, blockId, XYZ.Zero);
But this:
Viewport viewport = Viewport.Create(currentDoc, selectedSheet.Id, blockId, XYZ.Zero);

 

 

here is another answer from chat gpt:

 

In the method signature you provided:

 

csharpCopy code
public static Viewport Create(Document document, ElementId viewSheetId, ElementId viewId, XYZ point)

 

 

The parameter Document document refers to the document in which you want to create the viewport. Therefore, if you're importing ElementId viewId from another document, you should pass the document where that viewId belongs as the first argument (document).

So, if viewId is from the external document (externalDoc in your code), then you should pass externalDoc as the document argument when calling the Viewport.Create method.

Here's how you would do it:

 

csharpCopy code
Viewport viewport = Viewport.Create(externalDoc, selectedSheet.Id, blockId, XYZ.Zero);
 

This ensures that the viewport is created in the correct document context, which is the document from which you're importing the drafting view represented by viewId. (PLEASE TEST IT AND LET ME KNOW IF YOU CAN. THANK YOU)

0 Likes
Message 3 of 3

ed_sa
Enthusiast
Enthusiast
Accepted solution
// Create a viewport for the duplicated drafting view
//Not this!
Viewport viewport = Viewport.Create(currentDoc, selectedSheet.Id, blockId, XYZ.Zero);
But this:
Viewport viewport = Viewport.Create(externalDoc, selectedSheet.Id, blockId, XYZ.Zero);
0 Likes