Can I create a new layer and then add a few entities in that layers in newly created database?
Somethink like this
private void DodavanjePoligona(ref Database newDB, string imeLayera, Point2dCollection tockeCestica) { Random random = new Random(); //using (DocumentLock doclock = doc.LockDocument()) //{ using (Transaction trans = newDB.TransactionManager.StartTransaction()) { LayerTable layerKolekcija = trans.GetObject(newDB.LayerTableId, OpenMode.ForRead) as LayerTable; if (layerKolekcija.Has(imeLayera) == false) { LayerTableRecord ltr = new LayerTableRecord(); ltr.Color = Color.FromRgb((byte)random.Next(255), (byte)random.Next(255), (byte)random.Next(255)); ltr.Name = imeLayera; layerKolekcija.UpgradeOpen(); layerKolekcija.Add(ltr); trans.AddNewlyCreatedDBObject(ltr, true); } BlockTableRecord btr = trans.GetObject(newDB.CurrentSpaceId, OpenMode.ForWrite) as BlockTableRecord; Polyline cestica = new Polyline(); int count = 0; foreach (Point2d toc in tockeCestica) { cestica.AddVertexAt(count, toc, 0, 0, 0); count++; } try { cestica.Layer = imeLayera; } catch (Exception ex) { } btr.AppendEntity(cestica); trans.AddNewlyCreatedDBObject(cestica, true); trans.Commit(); } //} }
It crashes at try block...
But when I save newDB and open it, I can see that new layers has been created
Solved! Go to Solution.
Solved by jamierobertson1. Go to Solution.
Just for fun - current document ;
[CommandMethod("Test101001")]
public void Test101001()
{
Database db = AcadApp.DocumentManager.MdiActiveDocument.Database;
string layerName;
Point2dCollection pts = new Point2dCollection();
pts.Add(new Point2d(0.0, 0.0));
pts.Add(new Point2d(150.0, 0.0));
pts.Add(new Point2d(150.0, 100.0));
pts.Add(new Point2d(0.0, 200.0));
layerName = "TestLayer_1";
DodavanjePoligona(ref db, layerName, pts);
pts.Clear();
pts.Add(new Point2d(20.0, 20.0));
pts.Add(new Point2d(170.0, 20.0));
pts.Add(new Point2d(170.0, 120.0));
pts.Add(new Point2d(20.0, 220.0));
layerName = "TestLayer_2";
DodavanjePoligona(ref db, layerName, pts);
AcadApp.DocumentManager.MdiActiveDocument.Editor.WriteMessage("\nDone: ");
}
and - new Document ;
[CommandMethod("Test101003", CommandFlags.Session)]
public void Test101003()
{
// Create a new document database
DocumentCollection docMgr = Application.DocumentManager;
Document acNewDoc = docMgr.Add("acadiso.dwt");
Database acDbNewDoc = acNewDoc.Database;
string layerName;
Point2dCollection pts = new Point2dCollection();
pts.Add(new Point2d(0.0, 0.0));
pts.Add(new Point2d(150.0, 0.0));
pts.Add(new Point2d(150.0, 100.0));
pts.Add(new Point2d(0.0, 200.0));
layerName = "TestLayer_1";
// Lock the new document
using (DocumentLock acDocLock = acNewDoc.LockDocument())
{
DodavanjePoligona(ref acDbNewDoc, layerName, pts);
} // Unlock the document
pts.Clear();
pts.Add(new Point2d(20.0, 20.0));
pts.Add(new Point2d(170.0, 20.0));
pts.Add(new Point2d(170.0, 120.0));
pts.Add(new Point2d(20.0, 220.0));
layerName = "TestLayer_2";
// Lock the new document
using (DocumentLock acDocLock = acNewDoc.LockDocument())
{
DodavanjePoligona(ref acDbNewDoc, layerName, pts);
pts.Clear();
pts.Add(new Point2d(40.0, 40.0));
pts.Add(new Point2d(190.0, 40.0));
pts.Add(new Point2d(190.0, 140.0));
pts.Add(new Point2d(40.0, 240.0));
layerName = "TestLayer_3";
DodavanjePoligona(ref acDbNewDoc, layerName, pts);
} // Unlock the document
// Set the new document current
docMgr.MdiActiveDocument = acNewDoc;
}
// 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
Just a side note:
You may be best to add a functional statement to the catch rather than leave it empty.
//
Random objects that are instantiated in close succession generate an identical series of random numbers ...
So,
If you really want random colors for your layers it may be best to generate the Random object once in the calling routine and re-use it for each call to the DodavanjePoligona
.
// 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
@KerryBrown wrote:
How are you calling this ??
Can you post the calling code including the CommandMethod Attribute Statement
This method is calling from a button on form and form is calling like this
[CommandMethod("energo")] public void energo() { EnergoForma FormaEnergometana = new EnergoForma(); FormaEnergometana.Show(); }
and the calling method
DodavanjePoligona(ref newDB,opcina, kolekcijaTockakaCestice);
What you've posted is very little use for me to help you.
Did the code I posted help at all. ?
Are you locking the document ?
Did you try using
[CommandMethod("myCommand", CommandFlags.Session)]
// 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
Also I noticed and if Kerry agree's
you should consider using
Application.ShowModelessDialog()
or
Application.ShowModalDialog()
Sorry for my delay of answering to you all.
So, here is new code and the same thing is happing in this code
void UbacivanjeObjekataUDB(object[] podaciOObjektu) { ObjectId idBlocka; Point2d tempTocka; BlockReference block; string data; string data1; Random random = new Random(); string feature = podaciOObjektu.GetValue(0).ToString(); using (DocumentLock docLock = doc.LockDocument()) { using (Transaction trans = newDB.TransactionManager.StartTransaction()) { BlockTable bt = trans.GetObject(newDB.BlockTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead) as BlockTable; BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite) as BlockTableRecord; switch (feature) { case "fasadni": LayerTable layerKolekcija = trans.GetObject(newDB.LayerTableId, OpenMode.ForRead) as LayerTable; if (layerKolekcija.Has(feature) == false) { LayerTableRecord ltr = new LayerTableRecord(); ltr.Color = Color.FromRgb((byte)random.Next(255), (byte)random.Next(255), (byte)random.Next(255)); ltr.Name = feature; layerKolekcija.UpgradeOpen(); layerKolekcija.Add(ltr); trans.AddNewlyCreatedDBObject(ltr, true); } idBlocka = bt["fas"]; tempTocka = (Point2d)podaciOObjektu.GetValue(1); block = new Autodesk.AutoCAD.DatabaseServices.BlockReference(new Autodesk.AutoCAD.Geometry.Point3d(tempTocka.X, tempTocka.Y, 0), idBlocka); block.Layer = feature; /// <--ERROR HERE eKeyNotFound btr.AppendEntity(block); trans.AddNewlyCreatedDBObject(block, true); break;
I'm not using ModelessDialog and commandFlag.Session
Can someone explain me what is the diference between commandFlags and what should I gain with ModelessDialog form?
Thank you all
Yes you must call Transaction.Commit()
And if you have nested transaction you must call Transaction.Commit() on all outer transaction. For it take effect.
The session command flag executes at the Application Context and you must lock your document, same for modless forms.
If you are working at the documrnt context then AutoCAD will handle locking the document for you.
Open the arxdoc.chm and in the index tab enter "locking" , "application execution contexts", "document execution contexts", and "document locking" and look at the info under that, for more detailed explanation.
I modified like this and it did not work
void KreiranjeLayera(string layer) { Random random = new Random(); using (DocumentLock docLock = doc.LockDocument()) { using (Transaction trans = newDB.TransactionManager.StartTransaction()) { LayerTable layerKolekcija = trans.GetObject(newDB.LayerTableId, OpenMode.ForWrite) as LayerTable; LayerTableRecord ltr = new LayerTableRecord(); ltr.Color = Color.FromRgb((byte)random.Next(255), (byte)random.Next(255), (byte)random.Next(255)); ltr.Name = layer; layerKolekcija.UpgradeOpen(); layerKolekcija.Add(ltr); trans.AddNewlyCreatedDBObject(ltr, true); trans.Commit(); } } } void UbacivanjeObjekataUDB(object[] podaciOObjektu) { ObjectId idBlocka; Point2d tempTocka; BlockReference block; string data; string data1; bool layerPostoji; string feature = podaciOObjektu.GetValue(0).ToString(); using (DocumentLock docLock = doc.LockDocument()) { switch (feature) { case "fasadni": layerPostoji = true; using (Transaction trans = newDB.TransactionManager.StartTransaction()) { LayerTable layerKolekcija = trans.GetObject(newDB.LayerTableId, OpenMode.ForRead) as LayerTable; layerPostoji = layerKolekcija.Has(feature); } if (!layerPostoji) KreiranjeLayera(feature); using (Transaction trans = newDB.TransactionManager.StartTransaction()) { BlockTable bt = trans.GetObject(newDB.BlockTableId, Autodesk.AutoCAD.DatabaseServices.OpenMode.ForRead) as BlockTable; BlockTableRecord btr = trans.GetObject(bt[BlockTableRecord.ModelSpace], Autodesk.AutoCAD.DatabaseServices.OpenMode.ForWrite) as BlockTableRecord; idBlocka = bt["fas"]; tempTocka = (Point2d)podaciOObjektu.GetValue(1); block = new Autodesk.AutoCAD.DatabaseServices.BlockReference(new Autodesk.AutoCAD.Geometry.Point3d(tempTocka.X, tempTocka.Y, 0), idBlocka); block.Layer = feature; btr.AppendEntity(block); trans.AddNewlyCreatedDBObject(block, true); } break;
it is funny but after I create layer and I ask LayerTable if it has that layer it says true but when I tried to attach that layer on some object it failes on this code "block.Layer = feature;"
I had this problem as well, Not sure why. I noticed that if I set the layer current with Dababase.Clayer and just added entites, they went into the new layer ok.
Can't find what you're looking for? Ask the community or share your knowledge.