- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report
I use VB.net for my commands.
I suspect there is a threading issue going on between my wpf and Autocad, (which is hosting the wpf through the palette set), because If i place the code directly under a command it all seems to work perfectly.
Problem 1:
I have selection code that allows the user to select multiple objects.(No problems here, works perfectly)
If I run the same code from a WPF button click event, the first selected item acts normally, then every selection afterwards lags and only the last item selected exists in the SelectionSet. However, if I preselect the items and then run the selection event, all items are read correctly.
Problem 2:
After the selection in Problem 1 is finished. I get all the layer names of the selected entities (OpenMode.ForRead) and store in a list of strings. I then read all the entities in the drawing with the same layernames and change their layer color index (Default is OpenMode.ForRead but UpgradeOpen all the IEnumerable entities). Sometimes this works, most of the time I get a fatal error and a message eNotOpenForWrite even though this entity has just been opened for write and still exists within the same transaction.
' -------------------------------------------------------------- ' WPF Event ' -------------------------------------------------------------- Private Sub Button_Select_Click(ByVal sender As Object, ByVal e As EventArgs) ' Get the Layer names from user selection ' Dim bRC As Boolean = False bRC = GetYKCSelection() If bRC = False Then Exit Sub End If ' Turn LayerGroup entities' color property Red ' TurnLayersRed() ' Regen drawing CurrentEditor.Regen() End Sub ' -------------------------------------------------------------- ' Selection ' -------------------------------------------------------------- Public Function GetYKCSelection() As Boolean Dim selectionSet As SelectionSet = Nothing If IsSomethingSelected = True Then ' Get Pre-selection selectionSet = GetCurrentSelection() Else ' Get Post-Selection selectionSet = GetNewSelection() '------------- Strange selection behavior happens here End If ' Leave if nothing selected If selectionSet Is Nothing Then Return Nothing End If LayerNames = New List(Of String) Dim ent As Entity = Nothing Using acTrans As Transaction = ActiveDocument.Database.TransactionManager.StartTransaction() For Each so As SelectedObject In selectionSet Try ent = acTrans.GetObject(so.ObjectId, OpenMode.ForRead) If ent IsNot Nothing Then If Not LayerNames.Contains(ent.Layer) Then LayerNames.Add(ent.Layer) End If End If Catch e As System.Exception End Try Next acTrans.Commit() End Using If LayerNames.Count > 0 Then Return True Else Return False End If End Function Public Sub TurnLayersRed() Dim iLayNameToGet As String = String.Empty Using gDB = GSTDatabase.FromActiveDocument() Using locked As DocumentLock = ActiveDocument.LockDocument For Each strLayer As String In LayerNames ' Get all Entities from the drawing ' where the layer name is the same as ' what we want and return all those ' entities ObjectId Dim entLayerList = From ent In gDB.ModelSpace().ForWrite() Where ent.Layer = strLayer Select ent For Each et As Entity In entLayerList Try ' Set current color layer index to Red If et.IsWriteEnabled Then '------------------ Fatal error happens here et.ColorIndex = 1 End If Catch acEx As Autodesk.AutoCAD.Runtime.Exception Continue For Catch ex As System.Exception Continue For End Try Next Next End Using End Using End Sub ' -------------------------------------------------------------- ''' <summary> ''' Checks if something has been selected ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Public Function IsSomethingSelected() As Boolean Dim psr As PromptSelectionResult = Nothing psr = CurrentEditor.SelectImplied() If psr.Status = PromptStatus.OK Then Return True End If End Function ' -------------------------------------------------------------- ''' <summary> ''' Gets the currently selected items (Pre-Selection) ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Public Function GetCurrentSelection() As SelectionSet Dim psr As PromptSelectionResult = Nothing psr = CurrentEditor.SelectImplied() If psr.Status = PromptStatus.OK Then Return psr.Value Else Return Nothing End If End Function ' -------------------------------------------------------------- ''' <summary> ''' Gets a new selection (Post-Selection) ''' </summary> ''' <returns></returns> ''' <remarks></remarks> Public Function GetNewSelection() As SelectionSet Dim psr As PromptSelectionResult = Nothing psr = CurrentEditor.SelectImplied() ' Clear the selection set Dim idarrayEmpty() As ObjectId CurrentEditor.SetImpliedSelection(idarrayEmpty) ' Prompt for selection psr = CurrentEditor.GetSelection() If psr.Status = PromptStatus.OK Then Return psr.Value Else Return Nothing End If End Function
The IEnumerable section for entity retrieval can be found at:
https://wtertinek.com/2016/07/06/linq-and-the-autocad-net-api-final-part/
This is a piece of a very large project. If a functional version is desired please email me and I will see what I can do.
I believe this is a thread issue because I have seen similar behavior when programming with CATIA (and that solution was to invoke the command)
I am not sure how or where to invoke the selection command nor how to Invoke an UpgradeOpen.
Any help would be awesome. Thank you!
Solved! Go to Solution.