I use the following function to return the Proerty Set values of a property set when knowing it's name. Does anyone know how to get it working for style based PSDs?
Public Function GetValuesFromPropertySetByName(ByVal pname As String, ByVal dbobj As AcadDb.DBObject) As System.Collections.ArrayList Dim setIds As ObjectIdCollection = AecPropDb.PropertyDataServices.GetPropertySets(dbobj) Dim values As System.Collections.ArrayList = New System.Collections.ArrayList() If setIds.Count = 0 Then Return values ' just return emtpy collection... End If Dim db As Database = HostApplicationServices.WorkingDatabase Dim tm As acDS.TransactionManager = db.TransactionManager Dim psId As ObjectId For Each psId In setIds Dim pset As AecPropDb.PropertySet = tm.GetObject(psId, OpenMode.ForRead, False, False) Dim pid As Integer Try pid = pset.PropertyNameToId(pname) values.Add(pset.GetValueAndUnitAt(pid)) Catch e As Autodesk.AutoCAD.Runtime.Exception ' most likely eKeyNotfound. End Try Next Return values End Function
The AecPropertySampleMgd in the Sample folder in the AutoCAD directory shows how to do just about everything with property sets including getting information from style based property sets.
In particular checkout the GetPropertySetsFromStyle method. It shows how to get all of the style property sets of an entity knowing only the entities ObjectId.
Thanks Keith - almost got it working now but it doesn't seem to report values from Property Sets that use formulas:
Private Function Get_Value_From_Automatic_PropertySet_By_Name(ByVal idSM As ObjectId, ByVal pname As String) As String Dim db As Database = HostApplicationServices.WorkingDatabase Dim tr As Transaction = db.TransactionManager.StartTransaction Dim result As String = "" Try Dim bt As BlockTable = CType(tr.GetObject(db.BlockTableId, OpenMode.ForRead, False), BlockTable) Dim btr As BlockTableRecord = CType(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForRead, False), BlockTableRecord) ' get the property sets collection on this entity Dim ent As Object = tr.GetObject(idSM, OpenMode.ForRead) ' MH: this is for entity. ' Dim idsPropSets As ObjectIdCollection = PropertyDataServices.GetPropertySets(ent) ' now, try with styles. Dim geoObj As Autodesk.Aec.DatabaseServices.Geo = CType(ent, Autodesk.Aec.DatabaseServices.Geo) Dim style As Object = tr.GetObject(geoObj.StyleId, OpenMode.ForRead) Dim idsPropSets As ObjectIdCollection = PropertyDataServices.GetPropertySets(style) ' ' how many property sets does it have? ' ed.WriteMessage(vbCrLf + vbCrLf + ent.GetRXClass.Name + " (" + ent.Handle.ToString + ") has " + _ 'idsPropSets.Count.ToString + " PropSets:") ' Loop all PropertySets Dim idPropSet As ObjectId Dim iPropSet As Integer = 0 For Each idPropSet In idsPropSets iPropSet += 1 Dim propSet As PropertySet = CType(tr.GetObject(idPropSet, OpenMode.ForRead), PropertySet) ' The trick to get the properties is to really loop the *definitions*! ' Then we can evaluate automatic ones from the very PropSetDef, ' or get static ones from PropSet Dim propSetDef As PropertySetDefinition = _ CType(tr.GetObject(propSet.PropertySetDefinition, OpenMode.ForRead), PropertySetDefinition) Dim propDefs As PropertyDefinitionCollection = propSetDef.Definitions 'ed.WriteMessage(vbCrLf + vbCrLf + " PropSet " + iPropSet.ToString + "[" _ '+ propSetDef.Name + "] has " + propDefs.Count.ToString + " Props:") ' Loop all properties in the propSetDef Dim propDef As PropertyDefinition Dim iProp As Integer = 0 For Each propDef In propDefs iProp += 1 Dim value As String If (propDef.Automatic) Then 'AUTOMATIC Dim idsDummy As ObjectIdCollection = New ObjectIdCollection() value = propSetDef.GetValue(propDef.Id, idSM, idsDummy).ToString 'ed.WriteMessage(vbCrLf + " " + iProp.ToString + _ '".(AUTO) Name=" + propDef.Name + " Value=" + value) If propDef.Name = pname Then Return value End If End If Next propDef Next idPropSet Return result tr.Commit() Catch Return Nothing tr.Abort() Finally tr.Dispose() End Try End Function 'Gets an automatic property set value. Won't work on formula property sets. Returns nothing if empty
I use this code snippet to get the value from a property set definition. It doesnt matter if it is automatic, formula, manual, etc. It just gets the value.
Sorry the code is in C#. Im too lazy to convert it.
private static List<ToolTipLine> GetPropertySetValues(Member member, PropertySetDefinition propertySetDefinition) { // List to hold the property set definitions to display in the tooltip List<ToolTipLine> list = new List<ToolTipLine>(); try { using ( Transaction transaction = member.Database.TransactionManager.StartOpenCloseTransaction()) { // Check to see if the Property Set is attached to the object. If it is not then // Just return a blank list. ObjectId propertySetId = PropertyDataServices.GetPropertySet(member, propertySetDefinition.Id); if (propertySetId.IsNull || propertySetId.IsErased) { return list; } PropertySet propertySet = transaction.GetObject(propertySetId, OpenMode.ForRead) as PropertySet; // Iterate through each property definition in the property set foreach (PropertyDefinition propertyDefinition in propertySetDefinition.Definitions) { try { // Make sure that the property set defintion is set to visible if (propertyDefinition.IsVisible) { // Get the ObjectID of the property set definition int propertyId = propertySet.PropertyNameToId(propertyDefinition.Name); // Get the value of the property definition object value = propertySet.GetAt(propertyId); string str = ""; if (value != null) { str = value.ToString(); } // Once the value of the property definition is known we can create a new item // For our list. ToolTipLine item = new ToolTipLine { Name = propertyDefinition.Name, Value = str, Order = propertyDefinition.DisplayOrder }; // Add the item to the list list.Add(item); } } catch { } } propertySet.Dispose(); // Sort the list of items so that they respect the order assigned in the property set definition list.Sort(); } } catch { } finally { } return list; }
The code is a little specific for what I am using it for but it does show how to get the value of any property definition.
Looks promising - will report back later when tested - urgent job on at the mo'! Mine is for a tooltip too.
Thanks K