新聞中心
在本文中,我們將創(chuàng)建一個‘Employee 對象’(包括一個圓,一個橢圓和一個多行文本對象),這個對象屬于一個自定義的EmployeeBlock’塊(這個塊駐留在‘EmployeeLayer’層,當在模型空間插入這個塊的時候,‘EmployeeLayer’層就會擁有這個塊的一個塊索引)。本章的每一個步驟中的代碼都可以運行,這樣做的目的可以使你更清楚地知道每一部分代碼完成的功能。第一步將簡要說明一下如何在模型空間創(chuàng)建一個圓。

創(chuàng)新互聯(lián)成都企業(yè)網(wǎng)站建設(shè)服務(wù),提供成都做網(wǎng)站、網(wǎng)站制作網(wǎng)站開發(fā),網(wǎng)站定制,建網(wǎng)站,網(wǎng)站搭建,網(wǎng)站設(shè)計,響應(yīng)式網(wǎng)站建設(shè),網(wǎng)頁設(shè)計師打造企業(yè)風格網(wǎng)站,提供周到的售前咨詢和貼心的售后服務(wù)。歡迎咨詢做網(wǎng)站需要多少錢:18982081108
這一章的重點是在AutoCAD中訪問數(shù)據(jù)庫的基礎(chǔ)。主要內(nèi)容包括事務(wù)處理(Transaction)、對象Id(ObjectId)、符號表(symbol tables,如塊表BlockTable和層表LayerTable)以及對象引用。使用的其它一些對象如顏色Color、三維點Point3d和三維向量Vector3d,都和各自的步驟有關(guān),但重點應(yīng)該放在數(shù)據(jù)庫基礎(chǔ)上。
1) 創(chuàng)建一個名為‘CREATE’的命令,它調(diào)用函數(shù)CreateEmployee()。這個函數(shù)用來在模型空間(MODELSPACE)的(10,10,0)點處創(chuàng)建一個半徑為2.0的圓:
- [CommandMethod("test")]
- public void createCircle()
- {
- //首先聲明我們要使用的對象
- Circle circle; //這個是我們要加入到模型空間的圓
- BlockTableRecord btr;//要加入圓,我們必須打開模型空間
- BlockTable bt; //要打開模型空間,我們必須通過塊表(BlockTable)來訪問它
- //我們使用一個名為‘Transaction’的對象,把函數(shù)中有關(guān)數(shù)據(jù)庫的操作封裝起來
- Transaction trans;
- //使用TransactionManager的StartTransaction()成員來開始事務(wù)處理
- trans = HostApplicationServices.WorkingDatabase.TransactionManager.StartTransaction();
- //現(xiàn)在創(chuàng)建圓……請仔細看這些參數(shù)——注意創(chuàng)建Point3d對象的‘New’和Vector3d的靜態(tài)成員ZAxis
- circle = new Circle(new Point3d(10, 10, 0), Vector3d.ZAxis, 2);
- bt = (BlockTable)trans.GetObject(HostApplicationServices.WorkingDatabase.BlockTableId, OpenMode.ForRead);
- //使用當前的空間Id來獲取塊表記錄——注意我們是打開它用來寫入
- btr = (BlockTableRecord)trans.GetObject(HostApplicationServices.WorkingDatabase.CurrentSpaceId,OpenMode.ForWrite );
- //現(xiàn)在使用btr對象來加入圓
- btr.AppendEntity(circle);
- trans.AddNewlyCreatedDBObject(circle, true); //并確定事務(wù)處理知道要加入圓!
- //一旦完成以上操作,我們就提交事務(wù)處理,這樣以上所做的改變就被保存了……
- trans.Commit();
- //…然后銷毀事務(wù)處理,因為我們已經(jīng)完成了相關(guān)的操作(事務(wù)處理不是數(shù)據(jù)庫駐留對象,可以銷毀)
- trans.Dispose();
- }
請仔細閱讀一下上面的代碼塊的結(jié)構(gòu),可以通過注釋來了解相關(guān)的細節(jié)。
注意:要編譯代碼,你必須導入Autodesk.AutoCAD.DatabaseServices 和Autodesk.AutoCAD.Geometry命名空間
運行這個函數(shù)來看看它是否可行。應(yīng)該會在圖形中創(chuàng)建一個在(10,10,0)處的半徑為2.0的白色的圓。
2) 我們可以減少代碼的輸入量,這可以通過聲明一個Database變量代替HostApplicationServices.WorkingDatabase來實現(xiàn):
- Database db = HostApplicationServices.WorkingDatabase;
使用這個變量來代替在代碼中出現(xiàn)的HostApplicationServices.WorkingDatabase。
3) 在上面的代碼中,我們沒有使用任何異常處理,而異常處理對一個正確的.NET應(yīng)用程序來說是非常重要的。我們要養(yǎng)成使用異常處理的好習慣,所以讓我們在這個函數(shù)中加入try-catch-finally。
4) 為了使代碼緊湊,我們可以把許多變量的聲明和初始化放在同一個語句中?,F(xiàn)在,你的代碼看起來應(yīng)該是這樣的:
- [CommandMethod("CREATE")]
- public void CREATEEMPLOYEE()
- {
- Database db = HostApplicationServices.WorkingDatabase;
- Transaction trans = db.TransactionManager.StartTransaction();
- try
- {
- Circle circle = new Circle(new Point3d(10, 10, 0), Vector3d.ZAxis, 2);
- BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForRead);
- BlockTableRecord btr = (BlockTableRecord)trans.GetObject(HostApplicationServices.WorkingDatabase.CurrentSpaceId,OpenMode.ForWrite);
- btr.AppendEntity(circle);
- trans.AddNewlyCreatedDBObject(circle, true);
- trans.Commit();
- }
- catch
- {
- ed.WriteMessage("Error ");
- }
- finally
- {
- trans.Dispose();
- }
- }
- End Function
運行你的代碼來進行測試……
上面的catch塊只顯示一個錯誤信息。實際的清理工作是在finally塊中進行的。這樣做的理由是如果在事務(wù)處理被提交(Commit())之前,Dispose()被調(diào)用的話,事務(wù)處理會被銷毀。我們認為如果在trans.Commit()之前出現(xiàn)任何錯誤的話,你應(yīng)該銷毀事務(wù)處理(因為Commit將永遠不會被調(diào)用)。如果在Dispose()之前調(diào)用了Commit(),也就是說沒有任何錯誤發(fā)生,那么事務(wù)處理將會被提交給數(shù)據(jù)庫。
所以基于上面的分析,Catch塊其實并不是必須的,因為它只用來通知用戶程序出現(xiàn)了一個錯誤。它將在下面的代碼中被去掉。
5) 現(xiàn)在讓我們在Employee對象加入剩下的部分:橢圓和多行文本的實例。
多行文本實體:
中心點應(yīng)該與圓心的創(chuàng)建一樣:
(建議:創(chuàng)建一個名為‘center’而值為10,10,0的Point3d變量來表示中心點)
多行文本的內(nèi)容可以是你的名字。
橢圓(提示:你可以先看一下Ellipse的構(gòu)造函數(shù))
法向量應(yīng)該沿著Z軸(請查看Vector3d類型)
主軸設(shè)為Vector3d(3,0,0)(提示:不要忘了用new)
半徑比例設(shè)為0.5
橢圓還必須閉合(也就是說,開始和結(jié)束點必須相同)
運行你的代碼來進行測試……應(yīng)該可以生成一個圓、一個橢圓和一個中心點在10,10,0的多行文本。
注意:和事務(wù)處理對象有關(guān)的.NET API中的Try-Catch-Finally塊結(jié)構(gòu),應(yīng)該是異常觀察者。實際上我們是在try塊中實例化對象的,但沒有顯式地銷毀它們。當產(chǎn)生異常的時候可能會產(chǎn)生問題,特別是當觀察者注意到我們實際上用的是封裝的非托管對象!記住,當資源不再使用的時候,垃圾收集機制就會回收內(nèi)存。垃圾收集機制會不時的調(diào)用封裝類的Dispose()方法,刪除非托管對象。
這里還要注意的是Dispose()作用于封裝的非托管類對象的方式取決于對象是否是數(shù)據(jù)庫駐留對象。由非數(shù)據(jù)庫駐留對象調(diào)用的Dispose()會刪除非托管對象,而由數(shù)據(jù)庫駐留對象調(diào)用的Dispose()只是關(guān)閉它們。
6) 接下來讓我們來創(chuàng)建一個新的函數(shù),它用來新建一個顏色為黃色,名字為“EmployeeLayer” 的AutoCAD層。
這個函數(shù)應(yīng)該檢查是否這個層已經(jīng)存在,但不管這個層是否存在,函數(shù)都應(yīng)該返回“EmployeeLayer”的ObjectId。下面是這個函數(shù)的代碼:
- public ObjectId CreateLayer()
- {
- ObjectId layerId; //它返回函數(shù)的值
- Database db = HostApplicationServices.WorkingDatabase;
- Transaction trans = db.TransactionManager.StartTransaction();
- //首先取得層表……
- LayerTable lt = (LayerTable)trans.GetObject(db.LayerTableId, OpenMode.ForWrite);
- //檢查EmployeeLayer層是否存在……
- if (lt.Has("EmployeeLayer"))
- {
- layerId = lt["EmployeeLayer"];
- }
- else
- {
- //如果EmployeeLayer層不存在,就創(chuàng)建它
- LayerTableRecord ltr = new LayerTableRecord();
- ltr.Name = "EmployeeLayer"; //設(shè)置層的名字
- ltr.Color = Color.FromColorIndex(ColorMethod.ByAci, 2);
- layerId = lt.Add(ltr);
- trans.AddNewlyCreatedDBObject(ltr, true);
- }
- trans.Commit();
- trans.Dispose();
- return layerId;
- }
是不是覺得這個函數(shù)的基本結(jié)構(gòu)與在模型空間加入實體的代碼比較類似?訪問數(shù)據(jù)庫的方法都是這樣的:使用事務(wù)處理來獲取數(shù)據(jù)庫對象,在符號表(模型空間所在的塊表也是符號表之一)中加入實體,然后讓事務(wù)處理知道。
7) 在這個函數(shù)中加入異常處理,就像在CreateEmployee函數(shù)中的一樣。
8) 接下來,改變新建層的顏色。下面是實現(xiàn)的代碼片斷,請把它加入到你的代碼中:
- ltr.Color = Color.FromColorIndex(ColorMethod.ByAci, 2)
注意:ColorMethod.ByAci可以讓我們使用AutoCAD ACI顏色索引……這里為2(表示黃色)。
回到CreateEmployee()函數(shù),加入把上面創(chuàng)建的幾個實體設(shè)置到EmployeeLayer層的代碼。聲明一個類型為ObjectId的變量,用CreateLayer函數(shù)的返回值給它賦值。使用每個實體(文本、圓和橢圓)的LayerId屬性設(shè)置它們所在的層。
例如: text.LayerId = empId
運行代碼來查看“EmployeeLayer”層是否已被創(chuàng)建,所有已創(chuàng)建的實體是否都在這一層上(應(yīng)該顯示為黃色)
10) 現(xiàn)在為各個實體設(shè)置不同的顏色,可以使用ColorIndex屬性(ColorIndex屬性表示AutoCAD的顏色)
圓為紅色-1
橢圓為綠色-3
文本為黃色-2
運行代碼,看看實體的顏色是否為設(shè)置的值,即使這些實體是在“EmployeeLayer”層上。
11) 接下來,我們要在AutoCAD數(shù)據(jù)庫中創(chuàng)建一個獨立的塊,然后把它插入到塊表而不是模型空間中。
首先把CreateEmployee函數(shù)的名字改為CreateEmployeeDefinition()。
加入以下代碼來創(chuàng)建一個獨立的塊:
- BlockTableRecord newBtr = new BlockTableRecord();
- newBtr.Name = "EmployeeBlock";
- newBtrId = bt.Add(newBtr);
- trans.AddNewlyCreatedDBObject(newBtr, true);
12) 現(xiàn)在,請稍微改動一下加入實體到模型空間的代碼(改為加入塊到塊表中,記得加入前要打開塊表)。
現(xiàn)在運行代碼,然后使用INSERT命令來檢查是否可以正確插入這個塊。
13) 最后,我們要創(chuàng)建一個位于模型空間的塊索引,它表示上面創(chuàng)建的塊的一個實例。這一步留給大家練習。
下面是你要遵循的最基本的步驟:
創(chuàng)建一個名為CreateEmployee新的函數(shù)
把命令屬性“CREATE”移動到CreateEmployee()
修改CreateEmployeeDefintion()來返回新創(chuàng)建的塊“EmployeeBlock”的ObjectId,操作的步驟請參考CreateLayer()的作法。
你需要修改CreateEmployeeDefintion()來查看塊表中是否已包含“EmployeeBlock”塊,如果包含這個塊,則返回它的ObjectId(做法與CreateLayer()一樣)。
提示:把‘bt’的聲明語句移動到try塊的頂部,使用BlockTable.Has()方法,把其它的代碼移動到else語句:
- try
- {
- //獲取BlockTable 對象
- BlockTable bt = (BlockTable)trans.GetObject(db.BlockTableId, OpenMode.ForWrite);
- if ((bt.Has("EmployeeBlock")))
- {
- newBtrId =bt["EmployeeBlock"];
- }
- else
- {
- …
在新創(chuàng)建的CreateEmployee()函數(shù)中創(chuàng)建一個新的BlockReference對象,并把它加入到模型空間。提示:我們可以使用CreateEmployeeDefinition()中引用模型空間的代碼,這些代碼在這里不需要了
在CreateEmployee中調(diào)用CreateEmployeeDefinition()函數(shù),使上面生成的BlockReference對象的BlockTableRecord()指向CreateEmployeeDefinition()函數(shù)。提示:請參考BlockReference的構(gòu)造函數(shù)。
這樣,我們自己的Employee對象就創(chuàng)建完成了。
名稱欄目:C#.NET教程:創(chuàng)建我們自己的Employee對象
鏈接地址:http://m.fisionsoft.com.cn/article/dppddpo.html


咨詢
建站咨詢
