.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Using LayoutManager Resets my Layouts

10 REPLIES 10
SOLVED
Reply
Message 1 of 11
Poncho_Slim
567 Views, 10 Replies

Using LayoutManager Resets my Layouts

I posted about this issue previously: opening-a-drawing-in-the-background-copying-a-layout-and-saving 

I have constructed a more confined funnel to where the issue is lying.
The problem that I am having is that my viewports keep resetting.

Poncho_Slim_0-1717197753168.png

I have noticed that this happens based on the context that I save and close my document in.

When I am talking about the order, I am referring to the order in which the Layouts are presented in an opened document:

[Model] [Layout1] [Layout2] [Layout3] [Layout4]


If I Save and Close the document on the Layout I am deleting [Layout4], the Layout before it receives this reset[Layout3].
If I Save and Close the document on the Layout before the one I am deleting [Layout3], that layout gets this reset [Layout3].

If I Save and Close the document on a random layout, say 3 layouts before the one I am deleting [Layout1], that layout gets this reset [Layout1].

If I Save and Close in Model Space, then nothing gets reset.


Here is the code that is using the LayoutManager and where I highly suspect is causing the viewport reset.

 

 

private void DeleteLayoutInDrawing(string LayoutName, string LayoutFileName)
{
    Database OriginalDB = HostApplicationServices.WorkingDatabase;
    try
    {
        using (Database db = new Database(false, true))
        {
            db.ReadDwgFile(LayoutFileName, System.IO.FileShare.ReadWrite, false, null); 
            HostApplicationServices.WorkingDatabase = db;
            LayoutManager lm = LayoutManager.Current;
            lm.DeleteLayout(LayoutName);
            db.SaveAs(LayoutFileName, DwgVersion.Current);
            HostApplicationServices.WorkingDatabase = OriginalDB;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

 

 
I was wondering if anyone has some thoughts on what is causing this.

I had this function in a transaction, and it still produced the same issue.

I have tried to set the CurrentLayout for the LayoutManager to "Model" but I dont think it was working. If someone know how I could do this. I feel like setting the CurrentLayout to ModelSpace would allow me to do the deletion without breaking anything.

This was happening in another instance that I was using LayoutManager, so I am hoping in fixing this, I can transfer that fix onto the other function.

Thank you!

10 REPLIES 10
Message 2 of 11
Poncho_Slim
in reply to: Poncho_Slim

This is driving me insane. I have tried everything.
Here is my current code, and it is still not working. Now saving and closing on the layout I am deleting does not Reset any other layout, but if I save and close on any other layout besides Model, it Resets that layout that I closed on. I've attempted to set the LayoutManager to Model space which stopped the bug happening for when I save and close on the layout I am deleting, but it is still doing this for the case that I described.

I really need some help on this.

private void DeleteLayoutInDrawing(string LayoutName, string LayoutFileName)
{
    Database OriginalDB = HostApplicationServices.WorkingDatabase;
    try
    {
        using (Database db = new Database(false, true))
        {
            db.ReadDwgFile(LayoutFileName, System.IO.FileShare.ReadWrite, false, null); 
            HostApplicationServices.WorkingDatabase = db;
            using(Transaction tr = db.TransactionManager.StartTransaction())
            {
                // Look through layouttable
                DBDictionary layoutDict = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
                foreach (DBDictionaryEntry entry in layoutDict)
                {
                    if (entry.Key == "Model")
                    {
                        LayoutManager lm = LayoutManager.Current;
                        MessageBox.Show($"{lm.CurrentLayout}\n{lm.LayoutCount}");
                        lm.SetCurrentLayoutId(entry.Value);
                        MessageBox.Show($"{lm.CurrentLayout}\n{lm.LayoutCount}");
                        if(lm.LayoutExists(LayoutName))
                        {
                            MessageBox.Show($"{lm.CurrentLayout}\n{lm.LayoutCount}");
                            lm.DeleteLayout(LayoutName);
                            lm.SetCurrentLayoutId(entry.Value);
                            MessageBox.Show($"{lm.CurrentLayout}\n{lm.LayoutCount}");
                            db.SaveAs(LayoutFileName, DwgVersion.Current);
                            break;
                        }
                    }
                }
            }
            HostApplicationServices.WorkingDatabase = OriginalDB;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}



Message 3 of 11

Why is your code calling Database.SaveAs() repeatedly inside of a foreach() Loop that iterates over each layout in the database? That does not make any sense at all. 

Message 4 of 11

So I followed the logic of there only being one model space, and if that model space is found, then the function does some work, and then Saves the database. This can only happen once since it then breaks out of the loop afterwards.

Message 5 of 11

I still do not understand the purpose of writing the loop and breaking out when you reach the model space layout. If. your objective is to simply delete a layout having a given name you don't need to write a loop you just get the object ID of that layout and delete it. You may have to set another layout to the current layout if that layout that you are deleting is the current layout but there's no need for a loop. I can't tell you if taking a more straightforward path to deleting the layout is going to solve the problem you're having. 

Message 6 of 11
Poncho_Slim
in reply to: Poncho_Slim

I have found the bug!
The other place that was causing this error was in another function in the same routine.

Here is the broken function:

private void ClearRSandDateFromDeltas(string RS, string FullPath)
{
    bool ModificationMadeModel = false;
    bool ModificationMadePaper = false;
    var OriginalDB = HostApplicationServices.WorkingDatabase;
    using (var db = new Database(false, true))
    {
        db.ReadDwgFile(FullPath, System.IO.FileShare.ReadWrite, true, "");
        db.CloseInput(true);
        HostApplicationServices.WorkingDatabase = db;

        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            // Clear the RS and Date from the Deltas
            BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

            BlockTableRecord btrmodel = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
            BlockTableRecord btrpaper = tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead) as BlockTableRecord;
            ModificationMadeModel = ClearDeltaRSandDate(tr, ref btrmodel, RS, FullPath);
            ModificationMadePaper = ClearDeltaRSandDate(tr, ref btrpaper, RS, FullPath);

            if (ModificationMadeModel || ModificationMadePaper)
            { 
                tr.Commit();
                db.SaveAs(FullPath, DwgVersion.Current);
            }
        }

    }
    HostApplicationServices.WorkingDatabase = OriginalDB;
}

private bool ClearDeltaRSandDate(Transaction tr, ref BlockTableRecord btr, string RS, string FullPath)
{
    bool ModificationMade = false;
    foreach (ObjectId id in btr)
    {
        Entity ent = tr.GetObject(id, OpenMode.ForRead) as Entity;
        if (ent is BlockReference)
        {
            BlockReference br = ent as BlockReference;
            if (br.Name == ("FullDeltaBlock"))
            {
                foreach (ObjectId attributeID in br.AttributeCollection)
                {
                    AttributeReference attRef = tr.GetObject(attributeID, OpenMode.ForRead) as AttributeReference;
                    if (attRef.TextString == $"RS-{RS}")
                    {
                        attRef.UpgradeOpen();
                        attRef.TextString = "";
                        ModificationMade = true;
                        Delta delta = new Delta();
                        delta.Handle = br.Handle.ToString();
                        delta.SelectViaDrawing(FullPath);
                        delta.RSSheet = 1;
                        foreach (ObjectId datesearchatt in br.AttributeCollection)
                        {
                            AttributeReference dateatt = tr.GetObject(datesearchatt, OpenMode.ForRead) as AttributeReference;
                            if (dateatt.Tag == "DATE")
                            {
                                dateatt.UpgradeOpen();
                                dateatt.TextString = "";
                                delta.Date = DateTime.Parse("2000-01-01");
                            }
                        }
                        delta.Update();
                    }
                }
            }
        }
    }
    return ModificationMade;
}

 

When I closed in model space, no viewport would be reset. When I saved and closed on the sheet I am deleting, no viewport would be reset, due to the function that does the deleting moving into model space. But it would still do it when I saved and closed in any other sheet.
I eventually came to the conclusion that it was not due to the layout manager, but instead the Modifications I was doing in "ModelSpace" while my LayoutManager was on a Layout that is not model space, i.e I am in Paperspace doing model space things.

 

Here is the fixed code. I will continue to test it because I am afraid of if I have to do PaperSpace modifications for other cases, for example: If a block is placed in PaperSpace, and I want to modify it. But for this general base case, this worked!

private void ClearRSandDateFromDeltas(string RS, string FullPath)
{
    bool ModificationMadeModel = false;
    bool ModificationMadePaper = false;
    var OriginalDB = HostApplicationServices.WorkingDatabase;
    using (var db = new Database(false, true))
    {
        db.ReadDwgFile(FullPath, System.IO.FileShare.ReadWrite, true, "");
        db.CloseInput(true);
        HostApplicationServices.WorkingDatabase = db;

        using (Transaction tr = db.TransactionManager.StartTransaction())
        {
            // Move the LayoutManager to the Model Space
            DBDictionary layoutDict = tr.GetObject(db.LayoutDictionaryId, OpenMode.ForRead) as DBDictionary;
            LayoutManager lm = LayoutManager.Current;
            foreach (DBDictionaryEntry entry in layoutDict)
            {
                if (entry.Key == "Model")
                {
                    lm.CurrentLayout = entry.Key;
                    break;
                }
            }

            // Clear the RS and Date from the Deltas
            BlockTable bt = tr.GetObject(db.BlockTableId, OpenMode.ForRead) as BlockTable;

            BlockTableRecord btrmodel = tr.GetObject(bt[BlockTableRecord.ModelSpace], OpenMode.ForRead) as BlockTableRecord;
            BlockTableRecord btrpaper = tr.GetObject(bt[BlockTableRecord.PaperSpace], OpenMode.ForRead) as BlockTableRecord;
            ModificationMadeModel = ClearDeltaRSandDate(tr, ref btrmodel, RS, FullPath);
            ModificationMadePaper = ClearDeltaRSandDate(tr, ref btrpaper, RS, FullPath);

            if (ModificationMadeModel || ModificationMadePaper)
            { 
                tr.Commit();
                db.SaveAs(FullPath, DwgVersion.Current);
            }
        }

    }
    HostApplicationServices.WorkingDatabase = OriginalDB;
}


I hope this helps anyone running into this issue as it was such a weird issue that I could not find anything on here in the forums.
 

Message 7 of 11
Poncho_Slim
in reply to: Poncho_Slim

I further consolidated the ModelSpace. No need for all that tomfoolery

LayoutManager lm = LayoutManager.Current;
lm.CurrentLayout = "Model";
Message 8 of 11

So, my thought process was to find model space and then set LayoutManager.Current to that, and when I find that, then I would check if the Layout I want to delete is there. If it is, delete it.
You are slightly correct in that I did not need to loop through layouts to find Model Space. I wrote cleaner code in one of my responses. This was before I realized I could just change the LayoutManager.Current directly without an ObjectId.

I realized the error was here as well as in another function.

Thank you for the response!
Message 9 of 11
Poncho_Slim
in reply to: Poncho_Slim

Here is the Updated DeleteLayout Function:

private void DeleteLayoutInDrawing(string LayoutName, string LayoutFileName)
{
    Database OriginalDB = HostApplicationServices.WorkingDatabase;
    try
    {
        using (Database db = new Database(false, true))
        {
            db.ReadDwgFile(LayoutFileName, System.IO.FileShare.ReadWrite, false, null); 
            HostApplicationServices.WorkingDatabase = db;
            using(Transaction tr = db.TransactionManager.StartTransaction())
            {
                LayoutManager lm = LayoutManager.Current;
                lm.CurrentLayout = "Model";
                if (lm.LayoutExists(LayoutName))
                {
                    lm.DeleteLayout(LayoutName);
                    lm.CurrentLayout = "Model";
                    db.SaveAs(LayoutFileName, DwgVersion.Current);
                }
            }
            HostApplicationServices.WorkingDatabase = OriginalDB;
        }
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message);
    }
}

 

Message 10 of 11
kdub_nz
in reply to: Poncho_Slim

 

I'd recommend that you add a finally block to your try/catch that has the statement

HostApplicationServices.WorkingDatabase = OriginalDB;

. . . just to be safe.

 

I assume you won't be deleting the last/only layout . . . but you may consider guarding against that happening.

 

Regards,

 

 

 


// Called Kerry in my other life.

Everything will work just as you expect it to, unless your expectations are incorrect.

class keyThumper<T> : Lazy<T>;      another  Swamper

Message 11 of 11
Poncho_Slim
in reply to: kdub_nz

That is a great idea! I will do that. Thank you.

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

Post to forums  

Forma Design Contest


AutoCAD Beta