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

Chang SelectionFilter during GetSelection

13 REPLIES 13
SOLVED
Reply
Message 1 of 14
Amremad
1589 Views, 13 Replies

Chang SelectionFilter during GetSelection

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

 

13 REPLIES 13
Message 2 of 14
fenton.webb
in reply to: Amremad

when the keyword is pressed, simply update your filter, then restart the GetSelection with the new filter. Or am I misunderstanding you?




Fenton Webb
AutoCAD Engineering
Autodesk

Message 3 of 14
Amremad
in reply to: fenton.webb

yes mr fenton that what i want ,

 

but how can i reload my selection after changing the filter of selection ???

Message 4 of 14
DiningPhilosopher
in reply to: Amremad

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.

Message 5 of 14

Perhaps you could try SendStringToExecute to start your command again passing the previous selection set as a LISP ss variable




Fenton Webb
AutoCAD Engineering
Autodesk

Message 6 of 14
fenton.webb
in reply to: fenton.webb

You could also use the acedSSSetFirst() with a UsePickset defined command to reselect the selection




Fenton Webb
AutoCAD Engineering
Autodesk

Message 7 of 14
Amremad
in reply to: DiningPhilosopher

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

Message 8 of 14
DiningPhilosopher
in reply to: Amremad

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):

 

       http://www.theswamp.org/index.php?topic=43970.0

Message 9 of 14
Amremad
in reply to: DiningPhilosopher

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?

Message 10 of 14
DiningPhilosopher
in reply to: Amremad

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.

 

 

Message 11 of 14
Amremad
in reply to: DiningPhilosopher

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?

Message 12 of 14
_gile
in reply to: Amremad

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);
            }
        }
    }
}

 



Gilles Chanteau
Programmation AutoCAD LISP/.NET
GileCAD
GitHub

Message 13 of 14
Amremad
in reply to: _gile

wow   Smiley Happy

 

i didn't think by this way , hahah ,

 

thanks mr _gile

Message 14 of 14
Amremad
in reply to: Amremad

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

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