.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Insert .dwg file and adding properties to dynamic block

45 REPLIES 45
Reply
Message 1 of 46
kapes13
1384 Views, 45 Replies

Insert .dwg file and adding properties to dynamic block

I have been working through a dynamic block insertion routine using .NET with ACAD 2006 and it is having trouble getting instructions to stick to AutoCAD to continue.

I have been able to insert a .dwg file and create it's block reference, and at insertion time I wish to modify and add dynamic properties but the block's IsDynamicBlock property remains false just after insertion. I have to leave the routine and re-read the block from model space to note the property as true.

I have seen examples and publications use similar logic as ways to do this but the property remains false using the examples and labs from Autodesk.

Perhaps the references are off a little, or ACAD 2006 doesen't respond to the logic the same, and there is no solidly published model available which explains the methods in enough detail to understand the mishap here. A good reference pointer or hint of why the IsDynamicBlock property remains false after this logic would be greatly appreciated.

Here is the snippet which I use to insert the block:
Dim dwgName As String = HostApplicationServices.Current.FindFile(CurrentFullBlock, acadApp.DocumentManager.MdiActiveDocument.Database, FindFileHint.Default)
Dim db As Database = New Database(False, False)
db.ReadDwgFile(dwgName, IO.FileShare.ReadWrite, True, "")
Dim BlkId As ObjectId
BlkId = doc.Database.Insert(dwgName, db, True)
Dim bt As BlockTable = tr.GetObject(doc.Database.BlockTableId, OpenMode.ForRead, True)
Dim btr As BlockTableRecord = DirectCast(tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite), BlockTableRecord)
Dim blockRefIds As ObjectIdCollection = btr.GetBlockReferenceIds(False, False)
'Dim btr As BlockTableRecord = tr.GetObject(bt(BlockTableRecord.ModelSpace), OpenMode.ForWrite)
Dim bref As New BlockReference(New Autodesk.AutoCAD.Geometry.Point3d(insertionPoint), BlkId)
btr.AppendEntity(bref)
tr.AddNewlyCreatedDBObject(bref, True)
'Try to modify dynamic properties:
'Define properties:
Dim insDynamicPropertyCollection As DynamicBlockReferencePropertyCollection
Dim insDynamicProp As DynamicBlockReferenceProperty
'Get a new value for bref - BUT IsDynamicBlock is false here - WHY Please?
If bref.IsDynamicBlock Then
For Each insDynamicProp In insDynamicPropertyCollection
'Get the properties for the block
Select Case insDynamicProp.PropertyName.ToUpper
Case "Put a case here"
insDynamicProp.Value = "Set a value here"
Case Else
MsgBox("Property was not found.")
End Select
Next
End If
'Commit the add:
tr.Commit()
bref.ExplodeToOwnerSpace()

That is all any suggestions on why the property was not true are appreciated.

Have a great day.
45 REPLIES 45
Message 41 of 46
Anonymous
in reply to: kapes13

Sorry, I don't see any "ReactToChange" method in your posted code.


--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5864517@discussion.autodesk.com...
It is there. Just above the work event routine. They work together. The handler verifies the event (i try to filter out the object's IsWriteEnabled first to no avail), the work event verifies the object, and sends a custom event to the custom form with this line:

Public Sub PublishEvent(ByVal objType As String, ByVal eventType As String, ByVal id As Object)
RaiseEvent ObjectChanged(objType, eventType, id)
End Sub

(palette set based). Which then responds by running these lines of code:
...
Case "Modified"
Dim int As Integer = FindRow(Me.dgridPanelList, id)
If int = -1 Then Exit Sub
Dim objPanelRow As DataGridViewRow = dgridPanelList.Rows(int)
Dim objPanel As srwlPanel = Building.Levels.ContainsPanel(id)
objPanelRow.Cells("PanelID").Value = objPanel.PanelID
objPanelRow.Cells("Panel").Value = objPanel.Name
objPanelRow.Cells("PlateHeight").Value = objPanel.PlateHeight
objPanelRow.Cells("Length").Value = objPanel.Length
objPanelRow.Cells("Shear").Value = objPanel.Shear
objPanelRow.Cells("Tension").Value = objPanel.Tension
objPanelRow.Cells("UnitMaxShear").Value = objPanel.UnitMaxShear
objPanelRow.Cells("PanelDirection").Value = (objPanel.Direction * 180 / Math.PI) 'from radians to degrees
objPanelRow.Cells("Level").Value = objPanel.Level.Name
objPanelRow.Cells("Material").Value = objPanel.Material
objPanelRow.Cells("FullHeight").Value = objPanel.FullHeight
objPanelRow.Cells("Co").Value = objPanel.Co
objPanelRow.Cells("Reaction1").Value = objPanel.Reaction1
objPanelRow.Cells("Reaction2").Value = objPanel.Reaction2
objPanelRow.Cells("StackedWalls").Value = objPanel.StackedWalls
Me.objBuilding_ObjectChanged("Level", "Modified", objPanel.Level.LevelID)

These lines start from the custom form's point of view and go to GET the properties from scratch, not from the DBObject.
Which then runs the get dynamic property function to return the 'Length' value to the form.
Message 42 of 46
foruma000256
in reply to: kapes13

This is the react to change code, which formats the event call to the form.

Public Sub ReactToChange(ByVal Check As Object)
Try
If Check(0) = False Then
Dim aex As New System.Exception("Error in finding local object, check object returned false.")
Throw aex
Exit Sub
End If
Dim ipe As Boolean = Palette.IgnorePanelEvents
Palette.IgnorePanelEvents = True
Select Case Check(1)
Case "PanelRef"
'Debug.Print(" PanelRef " & Check(2).ToString)
PublishEvent("Panel", "Modified", Check(2))
PublishEvent("Level", "Modified", Check(3))
Case "HoldDownRef"
'Debug.Print(" HoldDownRef " & Check(2).ToString)
Case "OpeningRef"
'Debug.Print(" OpeningRef " & Check(2).ToString)
PublishEvent("Opening", "Modified", Check(2))
PublishEvent("Level", "Modified", Check(3))
Case "Elevation"
'Debug.Print(" Elevation " & Check(2).ToString)
PublishEvent("Level", "Modified", Check(3))
End Select
Palette.IgnorePanelEvents = ipe
Catch ex As Exception
Dim aex As New System.Exception("Error Reacting to Erased: ", ex)
Throw aex
End Try
End Sub
Message 43 of 46
Anonymous
in reply to: kapes13

I can't really make sense of the bits and pieces of code you posted, but my guess is that you are trying to access the dynamic block reference's properties at a point when you can't, and it has something to do with the state of the object when it's modified from the properties palette. If the object is not open in a transaction, and is in the notifying state, opening the object in a transaction is probably going to fail.

The basic problem with reacting to events like this is that you can't do much from the handler of the event directly, and instead should only capture ObjectIds of notifying objects, and do nothing else.

Then at some later point you react on the captured ObjectIds, at a point when the objects are in an accessable state.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5864537@discussion.autodesk.com...
This is the react to change code, which formats the event call to the form.

Public Sub ReactToChange(ByVal Check As Object)
Try
If Check(0) = False Then
Dim aex As New System.Exception("Error in finding local object, check object returned false.")
Throw aex
Exit Sub
End If
Dim ipe As Boolean = Palette.IgnorePanelEvents
Palette.IgnorePanelEvents = True
Select Case Check(1)
Case "PanelRef"
'Debug.Print(" PanelRef " & Check(2).ToString)
PublishEvent("Panel", "Modified", Check(2))
PublishEvent("Level", "Modified", Check(3))
Case "HoldDownRef"
'Debug.Print(" HoldDownRef " & Check(2).ToString)
Case "OpeningRef"
'Debug.Print(" OpeningRef " & Check(2).ToString)
PublishEvent("Opening", "Modified", Check(2))
PublishEvent("Level", "Modified", Check(3))
Case "Elevation"
'Debug.Print(" Elevation " & Check(2).ToString)
PublishEvent("Level", "Modified", Check(3))
End Select
Palette.IgnorePanelEvents = ipe
Catch ex As Exception
Dim aex As New System.Exception("Error Reacting to Erased: ", ex)
Throw aex
End Try
End Sub
Message 44 of 46
foruma000256
in reply to: kapes13

Love these narrow threads its like reading newspaper articles....

So If I am to react 'after' the event is done processing, then I have to have another mechanism that runs on a timer? Something like this...

set boolean that tells acad event is being processed.
create log list of user events to run afterwards
create on timmer event that checks if acad event is running
if not then look in log list for user events to be run
lock all events and run user events until log is clean...

Think that will really work?

jvj
Message 45 of 46
Anonymous
in reply to: kapes13

The notification you need to handle is not exposed to managed
ObjectARX, but you can use the mixed-mode library at the URL
below to get it:

http://www.caddzone.com/AcEditorReactor.zip

Read the docs and run the test project.

The ModelessOperationEnded event is the one you're interested in.

--
http://www.caddzone.com

AcadXTabs: MDI Document Tabs for AutoCAD 2008
Supporting AutoCAD 2000 through 2008
http://www.acadxtabs.com

wrote in message news:5864618@discussion.autodesk.com...
Love these narrow threads its like reading newspaper articles....

So If I am to react 'after' the event is done processing, then I have to have another mechanism that runs on a timer? Something like this...

set boolean that tells acad event is being processed.
create log list of user events to run afterwards
create on timmer event that checks if acad event is running
if not then look in log list for user events to be run
lock all events and run user events until log is clean...

Think that will really work?

jvj
Message 46 of 46
foruma000256
in reply to: kapes13

I don't care what I read about you Tony, your da-man!!

Now I can flag the properties palette events and not run during them!! For 2 months now, I've been trying to solve this.

Thank you very much,

jvj

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost