hi every one
i added an keyword with GetSelection using PromptSelectionOptions , this keyword can detrimne ablock name after run my selection
Dim AcSelResult As PromptSelectionResult = Application.DocumentManager.MdiActiveDocument.Editor.GetSelection(AcSelOption, AcSelFtr)
now how can i reload my selection by new block name , without end command
cause my current selection take old selection filter ,
i hope you understand me
Solved! Go to Solution.
Solved by _gile. Go to Solution.
when the keyword is pressed, simply update your filter, then restart the GetSelection with the new filter. Or am I misunderstanding you?
yes mr fenton that what i want ,
but how can i reload my selection after changing the filter of selection ???
You can't alter a selection filter while selection is in progress, and there is no way to restart with the previously-selected objects to allow more interactive selection.
You can use the Editor's SelectionAdded event to filter a selection using more dynamic criteria.
Perhaps you could try SendStringToExecute to start your command again passing the previous selection set as a LISP ss variable
You could also use the acedSSSetFirst() with a UsePickset defined command to reselect the selection
thank you mr diningphilosopher for helping
Imports Autodesk.AutoCAD.Runtime Imports Autodesk.AutoCAD.EditorInput Imports Autodesk.AutoCAD.ApplicationServices Imports Autodesk.AutoCAD.DatabaseServices Imports Autodesk.AutoCAD.Geometry Public NotInheritable Class ChangeBlocks Private Shared MObject As String Private Shared Factor As Double Private Shared Modification As String Private Shared Type As String Private Shared TypedValues(0) As TypedValue Private Shared AcSelFtr As SelectionFilter Private Shared LFormat As String Public Shared Sub ChengeBlock() MObject = GetSetting("AMR LISP", "Chenge Block", "Object", "ALL") Factor = GetSetting("AMR LISP", "Chenge Block", "Factor", "0") Type = GetSetting("AMR LISP", "Chenge Block", "Type", "Text") LFormat = GetSetting("AMR LISP", "Check Level", "Format", "0.00") ' create selection filter with typedvalues 'Dim TypedValues(0) As TypedValue If MObject = "All" Then TypedValues.SetValue(New TypedValue(DxfCode.Start, "INSERT"), 0) Else TypedValues.SetValue(New TypedValue(DxfCode.BlockName, MObject), 0) End If AcSelFtr = New SelectionFilter(TypedValues) 'create keywords options for selection Dim AcSelOption As PromptSelectionOptions = New PromptSelectionOptions AcSelOption.Keywords.Add("Object") AcSelOption.Keywords.Add("FActor") AcSelOption.Keywords.Add("FOrmat") AcSelOption.Keywords.Add("Type") AcSelOption.MessageForAdding = (vbLf & "Select Object(s) or " & AcSelOption.Keywords.GetDisplayString(True)) AcSelOption.Keywords.Default = "Object" AddHandler AcSelOption.KeywordInput, AddressOf handle_KeywordInput Dim AcSelResult As PromptSelectionResult = Application.DocumentManager.MdiActiveDocument.Editor.GetSelection(AcSelOption, AcSelFtr) Dim Tr As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction() If AcSelResult.Status = PromptStatus.OK Then If Type = "Text" Then If ChangeText(AcSelResult.Value) = False Then Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & "invalid operation, try again") End If Else If EditScale(AcSelResult.Value) = False Then Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & "invalid operation, try again") End If End If End If Tr.Commit() Tr.Dispose() Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & "done") End Sub Private Shared Function ChangeText(MySelSet As SelectionSet) As Boolean Dim Tr As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction() If MySelSet IsNot Nothing Then For Each BlKID In MySelSet.GetObjectIds() Dim BlkRef As BlockReference = Tr.GetObject(BlKID, OpenMode.ForWrite) If BlkRef.AttributeCollection.Count > 0 Then Dim objId As ObjectId = BlkRef.AttributeCollection.Item(0) Dim attRef As AttributeReference = Tr.GetObject(objId, OpenMode.ForWrite) Dim Value As Double = Val(attRef.TextString) + Factor If Value = 0 Then attRef.TextString = "±" & Format(Value, LFormat) ElseIf Value > 0 Then attRef.TextString = "+" & Format(Value, LFormat) ElseIf Value < 0 Then attRef.TextString = Format(Value, LFormat) End If End If Next End If Tr.Commit() Tr.Dispose() Return True End Function Private Shared Function EditScale(MySelSet As SelectionSet) As Boolean Dim Tr As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction() If MySelSet IsNot Nothing Then For Each BlKID In MySelSet.GetObjectIds() Dim BlkRef As BlockReference = Tr.GetObject(BlKID, OpenMode.ForWrite) If Factor > 0 Then BlkRef.TransformBy(Matrix3d.Scaling(Factor, BlkRef.Position)) Else Return False End If Next End If Tr.Commit() Tr.Dispose() Return True End Function Private Shared Sub handle_KeywordInput(ByVal sender As Object, ByVal e As SelectionTextInputEventArgs) Select Case e.Input Case "Object" Dim Trans As Transaction = Application.DocumentManager.MdiActiveDocument.TransactionManager.StartTransaction() Dim AcEntOption As PromptEntityOptions = New PromptEntityOptions(vbLf & "Select base object") AcEntOption.Keywords.Add("All") AcEntOption.Keywords.Add(MObject) AcEntOption.Keywords(1).Visible = False AcEntOption.Keywords.Default = MObject AcEntOption.SetRejectMessage(vbLf & "You must pick a block , try again ...") AcEntOption.AddAllowedClass(GetType(BlockReference), True) Dim AcEntResult As PromptEntityResult = Application.DocumentManager.MdiActiveDocument.Editor.GetEntity(AcEntOption) If AcEntResult.Status = PromptStatus.OK Then Dim Obj As DBObject = Trans.GetObject(AcEntResult.ObjectId, OpenMode.ForRead) If TypeOf (Obj) Is BlockReference Then Dim Source As BlockReference = Obj MObject = Source.Name SaveSetting("AMR LISP", "Chenge Block", "Object", MObject) 'TypedValues.SetValue(New TypedValue(DxfCode.Start, MObject), 0) 'AcSelFtr = New SelectionFilter(TypedValues) End If ElseIf AcEntResult.Status = PromptStatus.Keyword Then Select Case AcEntResult.StringResult Case "All" MObject = "All" SaveSetting("AMR LISP", "Chenge Block", "Object", MObject) 'TypedValues.SetValue(New TypedValue(DxfCode.BlockName, MObject), 0) 'AcSelFtr = New SelectionFilter(TypedValues) End Select Else Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & "you are selected unsupported object") End If Trans.Commit() Trans.Dispose() Case "FActor" L2: Dim AcDblOption As PromptDoubleOptions = New PromptDoubleOptions(vbLf & "Enter the calculation unit (Meter Unit) ") AcDblOption.AllowNone = False AcDblOption.DefaultValue = Factor If Type = "Text" Then AcDblOption.AllowNegative = True Else AcDblOption.AllowNegative = False End If Dim AcDblResult As PromptDoubleResult = Application.DocumentManager.MdiActiveDocument.Editor.GetDouble(AcDblOption) If AcDblResult.Status = PromptStatus.OK Then If Type = "Size" And AcDblResult.Value <= 0 Then Application.DocumentManager.MdiActiveDocument.Editor.WriteMessage(vbLf & "Value must be positive.") GoTo L2 End If Factor = AcDblResult.Value SaveSetting("AMR LISP", "Chenge Block", "Factor", Factor) Else End If Case "Type" Dim AcKwrdOption2 As PromptKeywordOptions = New PromptKeywordOptions(vbLf & "Which method you will use [Text/Size] : ", "Text Size") AcKwrdOption2.Keywords.Default = Type Dim AcKwrdResult2 As PromptResult = Application.DocumentManager.MdiActiveDocument.Editor.GetKeywords(AcKwrdOption2) If AcKwrdResult2.Status = PromptStatus.OK Then Type = AcKwrdResult2.StringResult SaveSetting("AMR LISP", "Chenge Block", "Type", Type) End If Case "FOrmat" Dim AcStrOption As PromptStringOptions = New PromptStringOptions("Enter text format that you want :") AcStrOption.DefaultValue = LFormat Dim AcStrResult As PromptResult = Application.DocumentManager.MdiActiveDocument.Editor.GetString(AcStrOption) If AcStrResult.Status = PromptStatus.OK Then LFormat = AcStrResult.StringResult SaveSetting("AMR LISP", "Chenge Block", "Format", LFormat) End If End Select End Sub End Class
this code can edit all block size , or block attributes text
my problem if the user while selection change the block name , so i need to apply the new filter to current selection ,
or cancel selection by code, or any solution to fix this problem
Sorry, no time to pick apart that code, but as I mentioned, the best way to solve the problem is to use the Editor's SelectionAdded event.
Otherwise, the link below shows a kludge that allows you to use GetSelection() and start with an existing selection set that a user can edit (add to or remove from):
Thanks MR. DiningPhilosopher for your help
but SelectionAdded event. doesn't work what i want ,
i neet to update filter of currect selection .. Understand me?
Sorry, you're mistaken. Perhaps you don't understand how the event works.
You filter each object as it is selected, using any criteria you want.
You can change the filter criteria at any time.
Yes I can change the filter criteria at any time. but before start the selection
so , how can i after the selection method start >
see my completly code in the sub "handle_KeywordInput" in selection case "Object" , i change what user what filter to selectionset do.
understand me?
No, as DiningPhilosopher said, using Editor.SelectionAdded you can change the way you filter objects after the selection started.
Try this little snippet, it starts filtering lines and you can change the filtered entities to circles or polylines during the selection. The selection set keeps previously selected objects.
using System.Collections.Generic; using Autodesk.AutoCAD.ApplicationServices; using Autodesk.AutoCAD.DatabaseServices; using Autodesk.AutoCAD.EditorInput; using Autodesk.AutoCAD.Runtime; namespace SelectionSample { public class CommandMethods { // current keyword filter private string keyWord; [CommandMethod("Test")] public void Test() { Editor ed = Application.DocumentManager.MdiActiveDocument.Editor; // (re)set default filter this.keyWord = "LIne"; PromptSelectionOptions opt = new PromptSelectionOptions(); opt.SetKeywords("[CIrcle/LIne/POlyline]", "CIrcle LIne POlyline"); opt.MessageForAdding = "\nSelect objects or " + opt.Keywords.GetDisplayString(true); opt.KeywordInput += onKeywordInput; ed.SelectionAdded += onSelectionAdded; PromptSelectionResult psr = ed.GetSelection(opt); ed.SelectionAdded -= onSelectionAdded; if (psr.Status == PromptStatus.OK) ed.SetImpliedSelection(psr.Value); } private void onKeywordInput(object sender, SelectionTextInputEventArgs e) { this.keyWord = e.Input; } private void onSelectionAdded(object sender, SelectionAddedEventArgs e) { RXClass rxc; switch (this.keyWord) { case "POlyline": rxc = RXClass.GetClass(typeof(Polyline)); break; case "CIrcle": rxc = RXClass.GetClass(typeof(Circle)); break; default: rxc = RXClass.GetClass(typeof(Line)); break; } ObjectId[] ids = e.AddedObjects.GetObjectIds(); for (int i = 0; i < ids.Length; i++) { if (ids[i].ObjectClass != rxc) e.Remove(i); } } } }
i solve 90% of my problems
no , how can i clear old selection after selection another block during selection set working
e.Remove(i)
just delete new added items , but i can't access of pervious selected item