Kean Walmsley

July 2009

Sun Mon Tue Wed Thu Fri Sat
      1 2 3 4
5 6 7 8 9 10 11
12 13 14 15 16 17 18
19 20 21 22 23 24 25
26 27 28 29 30 31  

Twitter Updates

    follow me on Twitter



    « Implementing a custom AutoCAD object snap mode using .NET | Main | Displaying a context menu during a custom AutoCAD command using .NET »

    November 03, 2008

    Creating a custom AutoCAD table style using .NET

    The question of how to define a new table style programmatically has come up a couple of times over the last week or so, so this post shows how to approach this. I've used the code from this previous post as a basis for this post's.

    The important thing to know is that TableStyle objects are stored in a special dictionary, which can be accessed via a Database's TableStyleDictionaryId property. This ObjectId property allows you to access the dictionary, from which you can query the contents, determine whether your style exists and add a new one if it doesn't. The code to specify the colour and formatting of the table style is reasonably straightforward.

    Here's some C# code to define a new "Garish Table Style" with a red header/title area, yellow data area and magenta text throughout (better put on your sunglasses before running it... :-):

    using Autodesk.AutoCAD.ApplicationServices;

    using Autodesk.AutoCAD.DatabaseServices;

    using Autodesk.AutoCAD.EditorInput;

    using Autodesk.AutoCAD.Runtime;

    using Autodesk.AutoCAD.Colors;


    namespace TableAndStyleCreation

    {

      public class Commands

      {

        [CommandMethod("CTWS")]

        static public void CreateTableWithStyle()

        {

          Document doc =

            Application.DocumentManager.MdiActiveDocument;

          Database db = doc.Database;

          Editor ed = doc.Editor;


          PromptPointResult pr =

            ed.GetPoint("\nEnter table insertion point: ");

          if (pr.Status == PromptStatus.OK)

          {

            Transaction tr =

              doc.TransactionManager.StartTransaction();

            using (tr)

            {

              // First let us create our custom style,

              //  if it doesn't exist


              const string styleName = "Garish Table Style";

              ObjectId tsId = ObjectId.Null;


              DBDictionary sd =

                (DBDictionary)tr.GetObject(

                  db.TableStyleDictionaryId,

                  OpenMode.ForRead

                );


              // Use the style if it already exists


              if (sd.Contains(styleName))

              {

                tsId = sd.GetAt(styleName);

              }

              else

              {

                // Otherwise we have to create it


                TableStyle ts = new TableStyle();


                // Make the header area red


                ts.SetBackgroundColor(

                  Color.FromColorIndex(ColorMethod.ByAci, 1),

                  (int)(RowType.HeaderRow | RowType.TitleRow)

                );


                // And the data area yellow


                ts.SetBackgroundColor(

                  Color.FromColorIndex(ColorMethod.ByAci, 2),

                  (int)RowType.DataRow

                );


                // With magenta text everywhere (yeuch :-)


                ts.SetColor(

                  Color.FromColorIndex(ColorMethod.ByAci, 6),

                  (int)(RowType.HeaderRow |

                        RowType.TitleRow |

                        RowType.DataRow)

                );


                // Add our table style to the dictionary

                //  and to the transaction


                sd.UpgradeOpen();

                tsId = sd.SetAt(styleName, ts);

                tr.AddNewlyCreatedDBObject(ts, true);

                sd.DowngradeOpen();

              }


              BlockTable bt =

                (BlockTable)tr.GetObject(

                  doc.Database.BlockTableId,

                  OpenMode.ForRead

                );


              Table tb = new Table();


              // Use our table style


              if (tsId == ObjectId.Null)

                // This should not happen, unless the

                //  above logic changes

                tb.TableStyle = db.Tablestyle;

              else

                tb.TableStyle = tsId;


              tb.NumRows = 5;

              tb.NumColumns = 3;

              tb.SetRowHeight(3);

              tb.SetColumnWidth(15);

              tb.Position = pr.Value;


              // Create a 2-dimensional array

              // of our table contents


              string[,] str = new string[5, 4];

              str[0, 0] = "Part No.";

              str[0, 1] = "Name ";

              str[0, 2] = "Material ";

              str[1, 0] = "1876-1";

              str[1, 1] = "Flange";

              str[1, 2] = "Perspex";

              str[2, 0] = "0985-4";

              str[2, 1] = "Bolt";

              str[2, 2] = "Steel";

              str[3, 0] = "3476-K";

              str[3, 1] = "Tile";

              str[3, 2] = "Ceramic";

              str[4, 0] = "8734-3";

              str[4, 1] = "Kean";

              str[4, 2] = "Mostly water";


              // Use a nested loop to add and format each cell


              for (int i = 0; i < 5; i++)

              {

                for (int j = 0; j < 3; j++)

                {

                  tb.SetTextHeight(i, j, 1);

                  tb.SetTextString(i, j, str[i, j]);

                  tb.SetAlignment(i, j, CellAlignment.MiddleCenter);

                }

              }

              tb.GenerateLayout();


              BlockTableRecord btr =

                (BlockTableRecord)tr.GetObject(

                  bt[BlockTableRecord.ModelSpace],

                  OpenMode.ForWrite

                );

              btr.AppendEntity(tb);

              tr.AddNewlyCreatedDBObject(tb, true);

              tr.Commit();

            }

          }

        }

      }

    }

    Here's what happens when we load the module and run the CTWS command, selecting a location for our "garish" table:

    Custom garishly-styled table

    And if we launch AutoCAD's TABLESTYLE command we can see our custom style in the list:

    AutoCAD's Table Style dialog with our new style

    Update

    A further post on this topic has now been published.

    TrackBack

    TrackBack URL for this entry:
    http://www.typepad.com/services/trackback/6a00d83452464869e2010535ca392e970c

    Listed below are links to weblogs that reference Creating a custom AutoCAD table style using .NET:

    Comments

    This sample is most appreciated by me - I have been really ... by the tables so far :)

    The sample works as expected. But I have some questions that you can help me out with (I use managed C++):

    (1) After creating the table, it doesn't have any style associated with it, its style id is null - we have to set a style to the table to get "expected results", right?

    (2) I tried placing the table in the paper space in the layout, and it didn't show up. It shows up properly in the model space, and the modelspace viewport in the layout. How can I fix this in the sample?

    Thanks for the sample!

    Gagan
    ==============

    Kean, Please ignore my question (2) in the previous post! I should have thought a bit before typing it!

    Thanks,

    Gagan
    ==============

    Hi Kean,
    I copied and run the code, but the result is not like yours. The most confused me is the title, in my table there were three columns showed "Name" and "Material". How can you hide these two columns and make the "Part No" center?

    I merged the first row's three columns to hide these two columns and make the "Part No" center, this can make my result as yours. But I didn't see any merge code in this example. Is there any other way to do that?

    To Gagan:
    Yse, after you create a table, the TableStyle'id is null, but it has a default table style, which you can see in "TABLESTYLE" command in AuotCAD, it's name is "default". This id will not assigned until you add the new table object to blocktable and commit the transaction.

    Travor,

    Actually, I now realise I didn't look very closely at the contents of the generated table when I put this post together...

    I didn't use merge code - the 0,0 cell ends up being used as the title (as I didn't suppress it).

    I'll post a new entry with the updated code - email me if you need it sooner.

    Regards,

    Kean

    Verify your Comment

    Previewing your Comment

    This is only a preview. Your comment has not yet been posted.

    Working...
    Your comment could not be posted. Error type:
    Your comment has been posted. Post another comment

    The letters and numbers you entered did not match the image. Please try again.

    As a final step before posting your comment, enter the letters and numbers you see in the image below. This prevents automated programs from posting comments.

    Having trouble reading this image? View an alternate.

    Working...

    Post a comment

    Feed & Share

    Search