Perhaps I didn't explain clearly enough. The code I posted works, but you may have been expecting it to do something it wasn't intended to do. It only shows how to call GetSelection() in a loop, and exit the loop when the user enters a keyword, by using an exception, and also shows how to add another keyword to the prompt. To change the keywords, you must exit the inner loop by throwing the exception. When it's caught you can then modify the keywords.
It might also help to point out that once GetSelection() is called, and up to the point when it returns, the PromptSelectionOptions you pass to it, is effectively read only, and any changes made to it from within a keyword input event handler will be ignored until the PromptSelectonOptions is again passed into a subsequent call to GetSelection().
In other words there are two loops. One is the loop within GetSelection() that iterates each time the user responds with a keyword. The only way to exit that internal loop is by throwing an exception that is caught within the outer loop. The other "outer" loop repeatedly calls GetSelection() with the same PromptSelectionOptions, which it can modify before each call to GetSelection() (e.g., to add/change/remove keywords).
Here is a slightly-more verbose version of the same code posted above, that displays a message each time you enter a keyword. Two of the keywords will exit the inner loop within GetSelection(), the "Change" keyword when entered, will add another keyword to the input prompt. The "Quit" keyword will exit both the inner and outer loops and return null.
public static class PromptSelectionWithKeyword
{
public static PromptSelectionResult GetSelectionWithKeywords(this Editor editor, params string[] keywords)
{
string keyword = null;
int i = 0;
PromptSelectionOptions pso = new PromptSelectionOptions();
pso.KeywordInput += OnKeywordInput;
foreach(string s in keywords)
pso.Keywords.Add(s);
pso.Keywords.Add("Quit");
pso.Keywords.Add("Change");
void OnKeywordInput(object sender, SelectionTextInputEventArgs e)
{
keyword = e.Input;
editor.WriteMessage($"User entered keyword {e.Input}");
if(e.Input == "Quit" || e.Input == "Change")
throw new KeywordException(e.Input); // break out of inner loop
// Otherwise, Select Objects: prompt is re-issued
// with the same keywords.
}
PromptSelectionResult result = null;
while(true)
{
try
{
string suffix = pso.Keywords.GetDisplayString(true);
pso.MessageForAdding = $"\nSelect objects or {suffix}";
result = editor.GetSelection(pso);
}
catch(KeywordException ex)
{
editor.WriteMessage($"\nGetSelection() exited, keyword = {ex.Keyword}");
if(ex.Keyword == "Quit")
{
return null; // Can't return PromptSelectionResult
}
else if(ex.Keyword == "Change")
{
/// Modify/add/remove keywords here
pso.Keywords.Add("NewKeyword");
}
continue;
}
return result;
}
}
public class KeywordException : System.Exception
{
string keyword;
public KeywordException(string keyword)
{
this.keyword = keyword;
}
public string Keyword => keyword;
}
[CommandMethod("SELECTWITHKEYWORDS")]
public static void Test()
{
Document doc = Application.DocumentManager.MdiActiveDocument;
Editor editor = doc.Editor;
var psr = editor.GetSelectionWithKeywords("FIrst", "Second", "Third");
if(psr == null)
editor.WriteMessage("\nUser chose Quit");
else
editor.WriteMessage($"\nresult.Status = {psr.Status}");
}
}
And here's what happens when I run it:
Command: SELECTWITHKEYWORDS
Select objects or [FIrst/Second/Third/Quit/Change]: First
User entered keyword FIrst
Select objects or [FIrst/Second/Third/Quit/Change]: Second
User entered keyword Second
Select objects or [FIrst/Second/Third/Quit/Change]: Change
User entered keyword Change
GetSelection() exited, keyword = Change
Select objects or [FIrst/Second/Third/Quit/Change/NewKeyword]: NewKeyword
User entered keyword NewKeyword
Select objects or [FIrst/Second/Third/Quit/Change/NewKeyword]: quit
User entered keyword Quit
GetSelection() exited, keyword = Quit
User chose Quit
Command: