TheSwamp

Code Red => .NET => Topic started by: Keith™ on May 26, 2017, 12:11:50 AM

Title: Problem setting TabOrder on Layouts
Post by: Keith™ on May 26, 2017, 12:11:50 AM
Maybe I am not understanding what needs to be done to re-order layouts, but I'm pretty certain that what I am doing isn't working ....
Code - C#: [Select]
  1. public void moveLayout(string name, bool up)
  2. {
  3.     Document acDoc = Autodesk.AutoCAD.ApplicationServices.Core.Application.DocumentManager.MdiActiveDocument;
  4.     Database acDB = acDoc.Database;
  5.     LayoutManager acLayoutMgr = LayoutManager.Current;
  6.     using (acDoc.LockDocument())
  7.     {
  8.         using (Transaction acTrans = acDB.TransactionManager.StartTransaction())
  9.         {
  10.             if (up)
  11.                 ((Layout)acTrans.GetObject(acLayoutMgr.GetLayoutId(name), OpenMode.ForWrite)).TabOrder -= 1;
  12.             else
  13.                 ((Layout)acTrans.GetObject(acLayoutMgr.GetLayoutId(name), OpenMode.ForWrite)).TabOrder += 1;
  14.             acTrans.Commit();
  15.             acDoc.Editor.Regen();
  16.         }
  17.     }
  18. }

I'm sure its something basic that I'm missing ... I seem to be having a forest/trees moment :-/
Title: Re: Problem setting TabOrder on Layouts
Post by: kdub_nz on May 26, 2017, 01:15:34 AM

I can't make time to play, but
Have you seen Normans blog post
http://drive-cad-with-code.blogspot.com.au/2011/06/set-layout-in-order.html
Title: Re: Problem setting TabOrder on Layouts
Post by: Bryco on May 26, 2017, 11:21:42 AM
Do you have to make it current before changing the taborder, manually you have to.
Title: Re: Problem setting TabOrder on Layouts
Post by: Keith™ on May 30, 2017, 11:30:32 PM

I can't make time to play, but
Have you seen Normans blog post
http://drive-cad-with-code.blogspot.com.au/2011/06/set-layout-in-order.html

I've seen that post. I wouldn't be averse to doing what it suggests if I could be assured it works as advertised. Right now, I am wanting to reorder a single tab up or down in the taborder.
I do have an idea that I will try and see of that resolves the issue.
Title: Re: Problem setting TabOrder on Layouts
Post by: kdub_nz on May 31, 2017, 01:52:25 AM

What happens if you attempt setting 3 consecutive tabs as Taborder 2 ... that may give you an indicator why the code you are using is failing ...

I started to think about your issue and real life caught up with me, so ....

Title: Re: Problem setting TabOrder on Layouts
Post by: n.yuan on May 31, 2017, 11:18:43 AM

I can't make time to play, but
Have you seen Normans blog post
http://drive-cad-with-code.blogspot.com.au/2011/06/set-layout-in-order.html

I've seen that post. I wouldn't be averse to doing what it suggests if I could be assured it works as advertised. Right now, I am wanting to reorder a single tab up or down in the taborder.
I do have an idea that I will try and see of that resolves the issue.

Now that one of my old posts has been mentioned, let me chip in:

I think the reason of your code not working is because you simply try to change TabOrder of ONE layout, but did not try to change AFFECTED layout(s) (the ones before and/or after the one you change), which would result in duplicated TabOrder, thus exception when the Transaction is to commit. You see, there is always MODEL layout, which always has TabOrder=0. So, you cannot move layout with TabOrder=1 down. If the layout is has the max TabOrder, you cannot move it up. Therefore, when you say "re-order" layout tabs, it is actually SWAP TabOrder of 2 layouts: targeted one and the one before it (as long as it is not "MODEL"), or the one after it (as long as it is not the last one).

Once you understand this, things are really simple. Here is the code that works for me:

Code: [Select]
public static void SwapLayoutTabOrder(ObjectId lay1Id, ObjectId lay2Id)
        {
            using (var tran = lay1Id.Database.TransactionManager.StartTransaction())
            {
                var layout1 = (Layout)tran.GetObject(lay1Id, OpenMode.ForWrite);
                var layout2 = (Layout)tran.GetObject(lay2Id, OpenMode.ForWrite);

                var order1 = layout1.TabOrder;
                var order2 = layout2.TabOrder;

                layout1.TabOrder = order2;
                layout2.TabOrder = order1;

                tran.Commit();
            }
        }

The 2 arguments of the method are 2 layout's ObjectId, as long as none of them being "Model" layout.

I Just did a full demo-able project with UI to verify the code works as I expected. For the benefit of other possible readers to see the the code of entire project, I'll publish it in my blog later today, and post link here
Title: Re: Problem setting TabOrder on Layouts
Post by: n.yuan on May 31, 2017, 12:13:27 PM
OK, I published full code here

http://drive-cad-with-code.blogspot.ca/2017/05/swap-layout-order.html (http://drive-cad-with-code.blogspot.ca/2017/05/swap-layout-order.html)

Title: Re: Problem setting TabOrder on Layouts
Post by: kdub_nz on May 31, 2017, 08:04:13 PM

Thanks Norman.

Very professional, as usual.

Regards,


Title: Re: Problem setting TabOrder on Layouts
Post by: Keith™ on May 31, 2017, 11:44:41 PM

I think the reason of your code not working is because you simply try to change TabOrder of ONE layout, but did not try to change AFFECTED layout(s) (the ones before and/or after the one you change), which would result in duplicated TabOrder, thus exception when the Transaction is to commit.

That's the issue that I had come to the conclusion was happening. I'll review your code and see how I can incorporate a similar approach in my project. I sincerely appreciate the assistance.

Incidentally, I was not getting any kind of error, it just did not work.
Title: Re: Problem setting TabOrder on Layouts
Post by: Keith™ on June 05, 2017, 06:42:38 PM
Setting TabOrder on all tabs affected resolved the issue.
Thanks for the help .. its amazing how a small thing can cause such a problem!

Now its off to figure out another thing that I have been dreading ...