Kean Walmsley


  • About the Author
    Kean on Google+

April 2014

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      







« Accessing the hidden _name property via the Design Review API | Main | Selecting the nearest face of an AutoCAD solid using .NET »

January 15, 2009

More fun with AutoCAD tables and their styles using .NET

In this previous post we saw some code to create a table style and apply it to a new table inside an AutoCAD drawing. While responding to a comment on the post, I realised that the table didn't display properly using my example: the first column heading was being taken as the table title and the rest of the column headings were lost - the headings in the table were actually taken from the first row of data. I suppose that serves me right for having chosen such eye-catching (and distracting) colours. :-)

The following C# code addresses this by adding some information to our array of table contents, and using that for the table title. It also does a little more to customize the display of our table by applying chunky lineweights (and yet more garish colours) to the table's grid-lines.

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 CreateTableWithStyleAndWhatStyle()

    {

      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.TitleRow |

                    RowType.HeaderRow)

            );

 

            // 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.TitleRow |

                    RowType.HeaderRow |

                    RowType.DataRow)

            );

 

            // And now with cyan outer grid-lines

 

            ts.SetGridColor(

              Color.FromColorIndex(ColorMethod.ByAci, 4),

              (int)GridLineType.OuterGridLines,

              (int)(RowType.TitleRow |

                    RowType.HeaderRow |

                    RowType.DataRow)

            );

 

            // And bright green inner grid-lines

 

            ts.SetGridColor(

              Color.FromColorIndex(ColorMethod.ByAci, 3),

              (int)GridLineType.InnerGridLines,

              (int)(RowType.TitleRow |

                    RowType.HeaderRow |

                    RowType.DataRow)

            );

 

            // And we'll make the grid-lines nice and chunky

 

            ts.SetGridLineWeight(

              LineWeight.LineWeight211,

              (int)GridLineType.AllGridLines,

              (int)(RowType.TitleRow |

                    RowType.HeaderRow |

                    RowType.DataRow)

            );

 

            // Add our table style to the dictionary

            //  and to the transaction

 

            tsId = ts.PostTableStyleToDatabase(db, styleName);

            tr.AddNewlyCreatedDBObject(ts, true);

          }

 

          BlockTable bt =

            (BlockTable)tr.GetObject(

              doc.Database.BlockTableId,

              OpenMode.ForRead

            );

 

          Table tb = new Table();

 

          tb.NumRows = 6;

          tb.NumColumns = 3;

          tb.SetRowHeight(3);

          tb.SetColumnWidth(15);

          tb.Position = pr.Value;

 

          // 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;

 

          // Create a 2-dimensional array

          // of our table contents

 

          string[,] str = new string[6, 3];

          str[0, 0] = "Material Properties Table";

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

          str[1, 1] = "Name";

          str[1, 2] = "Material";

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

          str[2, 1] = "Flange";

          str[2, 2] = "Perspex";

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

          str[3, 1] = "Bolt";

          str[3, 2] = "Steel";

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

          str[4, 1] = "Tile";

          str[4, 2] = "Ceramic";

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

          str[5, 1] = "Kean";

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

 

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

 

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

          {

            if (i == 0)

            {

              // This is for the title

 

              tb.SetTextHeight(0, 0, 1);

              tb.SetTextString(0, 0, str[0, 0]);

              tb.SetAlignment(0, 0, CellAlignment.MiddleCenter);

            }

            else

            {

              // These are the header and data rows

 

              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();

        }

      }

    }

  }

}

One other minor enhancement: I made use of the TableStyle.PostTableStyleToDatabase() method to add the style to the appropriate location in the Database (we previously edited the TableStyleDictionary directly to achieve this).

Here's what happens when we run the CTWS command (making sure that we have adjusted the display settings to use lineweights):

Another custom garishly-styled table

And here's the updated style in AutoCAD's TableStyle dialog:

AutoCAD's Table Style dialog with our updated style

That's better. At least in that it does what was expected of it, even if it's not winning any design awards. :-)

Update

Roland Feletic pointed out that this code - while it still builds for AutoCAD 2011 - causes some "obsolete property/method" compiler warnings. I've provided an updated version of the code below, with the previous lines commented out for comparison:

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 CreateTableWithStyleAndWhatStyle()

    {

      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.TitleRow |

                    RowType.HeaderRow)

            );

 

            // 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.TitleRow |

                    RowType.HeaderRow |

                    RowType.DataRow)

            );

 

            // And now with cyan outer grid-lines

 

            ts.SetGridColor(

              Color.FromColorIndex(ColorMethod.ByAci, 4),

              (int)GridLineType.OuterGridLines,

              (int)(RowType.TitleRow |

                    RowType.HeaderRow |

                    RowType.DataRow)

            );

 

            // And bright green inner grid-lines

 

            ts.SetGridColor(

              Color.FromColorIndex(ColorMethod.ByAci, 3),

              (int)GridLineType.InnerGridLines,

              (int)(RowType.TitleRow |

                    RowType.HeaderRow |

                    RowType.DataRow)

            );

 

            // And we'll make the grid-lines nice and chunky

 

            ts.SetGridLineWeight(

              LineWeight.LineWeight211,

              (int)GridLineType.AllGridLines,

              (int)(RowType.TitleRow |

                    RowType.HeaderRow |

                    RowType.DataRow)

            );

 

            // Add our table style to the dictionary

            //  and to the transaction

 

            tsId = ts.PostTableStyleToDatabase(db, styleName);

            tr.AddNewlyCreatedDBObject(ts, true);

          }

 

          BlockTable bt =

            (BlockTable)tr.GetObject(

              doc.Database.BlockTableId,

              OpenMode.ForRead

            );

 

          Table tb = new Table();

 

          tb.InsertRows(0, 3, 6);

          tb.InsertColumns(0, 15, 3);

 

          /*

          tb.NumRows = 6;

          tb.NumColumns = 3;

          tb.SetRowHeight(3);

          tb.SetColumnWidth(15);

          tb.Position = pr.Value;

          */

 

          // 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;

 

          // Create a 2-dimensional array

          // of our table contents

 

          string[,] str = new string[6, 3];

          str[0, 0] = "Material Properties Table";

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

          str[1, 1] = "Name";

          str[1, 2] = "Material";

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

          str[2, 1] = "Flange";

          str[2, 2] = "Perspex";

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

          str[3, 1] = "Bolt";

          str[3, 2] = "Steel";

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

          str[4, 1] = "Tile";

          str[4, 2] = "Ceramic";

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

          str[5, 1] = "Kean";

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

 

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

 

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

          {

            if (i == 0)

            {

              // This is for the title

 

              tb.Cells[0, 0].TextHeight = 1;

              tb.Cells[0, 0].TextString = str[0, 0];

              tb.Cells[0, 0].Alignment =

                CellAlignment.MiddleCenter;

 

              //tb.SetTextHeight(0, 0, 1);

              //tb.SetTextString(0, 0, str[0, 0]);

              //tb.SetAlignment(0, 0, CellAlignment.MiddleCenter);

            }

            else

            {

              // These are the header and data rows

 

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

              {

                tb.Cells[i, j].TextHeight = 1;

                tb.Cells[i, j].TextString = str[i, j];

                tb.Cells[i, j].Alignment =

                  CellAlignment.MiddleCenter;

 

                //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();

        }

      }

    }

  }

}

Many thanks, Roland! :-)

TrackBack

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

Listed below are links to weblogs that reference More fun with AutoCAD tables and their styles using .NET:

blog comments powered by Disqus

10 Random Posts