TheSwamp
Code Red => .NET => Topic started by: waterharbin on September 04, 2012, 08:50:49 AM
-
Hi,
With the help of gile, I learn how to draw some lines with XRecord in this post: http://www.theswamp.org/index.php?topic=42203.msg473381#msg473381.
Now I have a new question: how to judge a line has XRecord or not. Because I need to select all the lines in a drawing.
Here is how to draw lines with XRecord:
Public Shared Function AddLine(ByVal startPt As Point3d, ByVal endPt As Point3d, ByVal Color As Integer, _
ByVal Name As String, ByVal Length As String, ByVal Top As String, ByVal Bottom As String) As ObjectId
Dim ed As Editor = Application.DocumentManager.MdiActiveDocument.Editor
Dim db As Database = HostApplicationServices.WorkingDatabase
'the objectId will be retured
Dim retVal As ObjectId = ObjectId.Null()
Using trans As Transaction = db.TransactionManager.StartTransaction
'Define the line
Dim acLine As Line = New Line
acLine.StartPoint = startPt
acLine.EndPoint = endPt
acLine.ColorIndex = Color
Dim btr As BlockTableRecord = trans.GetObject(db.CurrentSpaceId, OpenMode.ForWrite)
retVal = btr.AppendEntity(acLine)
trans.AddNewlyCreatedDBObject(acLine, True)
Dim Xrec As New Xrecord()
Xrec.Data = New ResultBuffer( _
New TypedValue(DxfCode.Text, Length), _
New TypedValue(DxfCode.Text, Top), _
New TypedValue(DxfCode.Text, Bottom))
acLine.CreateExtensionDictionary()
Dim xDict As DBDictionary = trans.GetObject(acLine.ExtensionDictionary, OpenMode.ForWrite)
xDict.SetAt(Name, Xrec)
trans.AddNewlyCreatedDBObject(Xrec, True)
trans.Commit()
End Using
Return retVal
End Function
Call the function to draw lines by something like:
Dim DoorIdCol As ObjectIdCollection = New ObjectIdCollection()
Dim WindowIdCol As ObjectIdCollection = New ObjectIdCollection()
'The arguments(Name not included) come form a form by user's inputing, that why they are String not Double
Dim DoorId = AddLine(pt1,pt2,1,"Door", "2000","400","800")
DoorIdCol.Add(DoorId)
Dim WindowId = AddLine(pt3,pt4,2,"Window","2200","400","0")
WindowIdCol.Add(WindowId)
I used to define ObjectIdCollections to hold the returned Ids everytime I draw one line, and get the XRecord back via the Ids. Now I found there is a loophole in this way: I use the Ids to get the XRecord back for the firt time, and in some cases, the ObjectIdCollections need to be cleared.Then, all the Ids are lost, I can not get the XRecord back again for a second use. So I wonder can I get the XRecord back by selecting the lines on the screen? Then I can get the XRecord back everytime I want.
Here is what I get at the present:
public void selectLine(ObjectIdCollection DoorIdCol,ObjectIdCollection WindowIdCol)
{
Document doc = Autodesk.AutoCAD.ApplicationServices.Application.DocumentManager.MdiActiveDocument;
Database db = doc.Database;
Editor ed = doc.Editor;
using (Transaction trans = db.TransactionManager.StartTransaction())
{
try
{
TypedValue[] tv = new TypedValue[] { new TypedValue((int)DxfCode.Start, "LINE") };
SelectionFilter flt = new SelectionFilter(tv);
PromptSelectionOptions optSel = new PromptSelectionOptions();
optSel.MessageForAdding = "Select Lines";
PromptSelectionResult resSel = ed.GetSelection(optSel, flt);
if (resSel.Status != PromptStatus.OK)
{
return false;
}
SelectionSet selSet = resSel.Value;
ObjectId[] ids = selSet.GetObjectIds();
foreach (ObjectId sSetEntId in ids)
{
Entity ent = (Entity)trans.GetObject(sSetEntId, OpenMode.ForWrite);
if (ent.GetType().Name == "Line")
{
Line myLine = (Line)trans.GetObject(sSetEntId, OpenMode.ForWrite); //get the line back
//How to judge this line has XRecord or not? If it has,how can I know it's a "Door" or a "Window"?
}
}
}
catch (System.Exception ex)
{
ed.WriteMessage(ex.Message + "\n" + ex.StackTrace);
return false;
}
trans.Commit();
}
}
Maybe I can get the Ids back by selcting the lines on the screen,everytime I need the Lines with XRecord, I select them on the screen, and get them Ids back.
-
Here is my extension method to get XRecord from object
/// <summary>
/// Returns Xrecord
/// </summary>
/// <param name="o">Object with Xrecord</param>
/// <param name="xrecordName">The name of Xrecord</param>
/// <returns>ResultBuffer with values of given Xrecord, or null, if object has not given Xrecord</returns>
public static ResultBuffer GetXrecord(this DBObject o, string xrecordName)
{
if (xrecordName == null)
throw new ArgumentNullException("xrecordName is null");
if (o.ExtensionDictionary != ObjectId.Null &&
!o.ExtensionDictionary.IsErased)
{
using (DBDictionary dict = (DBDictionary)o.ExtensionDictionary.GetObject(OpenMode.ForRead))
{
if (dict.Contains(xrecordName))
{
Xrecord xrecord = dict.GetAt(xrecordName).GetObject(OpenMode.ForRead) as Xrecord;
if (xrecord != null)
return xrecord.Data;
}
}
}
return null;
}
So, if it returns null - object hasn't given XRecord. Or you can iterate through ExtensionDictionary keys and see all XRecords