/// <summary> /// Provides a set of choices that enable the user to choose a one or more options /// from a set of options. /// </summary> /// <param name="caption">A title that proceeds the choices.</param> /// <param name="message"> /// An introduction message that describes the /// choices. /// </param> /// <param name="choices">A collection of ChoiceDescription objects that describe each choice.</param> /// <param name="defaultChoices"> /// The index of the label in the Choices parameter /// collection that indicates the default choice used if the user does not specify /// a choice. To indicate no default choice, set to -1. /// </param> /// <returns> /// The index of the Choices parameter collection element that corresponds /// to the choices selected by the user. /// </returns> public Collection <int> PromptForChoice( string caption, string message, Collection <ChoiceDescription> choices, IEnumerable <int> defaultChoices) { // Write the caption and message strings in Blue. WriteLine( RawUI.ForegroundColor, RawUI.BackgroundColor, caption + "\n" + message + "\n"); // Convert the choice collection into something that's a // little easier to work with // See the BuildHotkeysAndPlainLabels method for details. var promptData = BuildHotkeysAndPlainLabels(choices); // Format the overall choice prompt string to display... var sb = new StringBuilder(); for (var element = 0; element < choices.Count; element++) { sb.Append(string.Format( CultureInfo.CurrentCulture, "|{0}> {1} ", promptData[0, element], promptData[1, element])); } var defaultResults = new Collection <int>(); if (defaultChoices != null) { var countDefaults = 0; var enumerable = defaultChoices as int[] ?? defaultChoices.ToArray(); foreach (var defaultChoice in enumerable) { ++countDefaults; defaultResults.Add(defaultChoice); } if (countDefaults != 0) { sb.Append(countDefaults == 1 ? "[Default choice is " : "[Default choices are "); foreach (var defaultChoice in enumerable) { sb.AppendFormat( CultureInfo.CurrentCulture, "\"{0}\",", promptData[0, defaultChoice]); } sb.Remove(sb.Length - 1, 1); sb.Append("]"); } } WriteLine(RawUI.ForegroundColor, RawUI.BackgroundColor, sb.ToString()); // loop reading prompts until a match is made, the default is // chosen or the loop is interrupted with ctrl-C. var results = new Collection <int>(); while (true) { ReadNext: var prompt = string.Format(CultureInfo.CurrentCulture, "Choice[{0}]:", results.Count); Write(RawUI.ForegroundColor, RawUI.BackgroundColor, prompt); var data = _debugger.ReadLine().Trim().ToUpper(CultureInfo.CurrentCulture); // if the choice string was empty, no more choices have been made. // if there were no choices made, return the defaults if (data.Length == 0) { return(results.Count == 0 ? defaultResults : results); } // see if the selection matched and return the // corresponding index if it did... for (var i = 0; i < choices.Count; i++) { if (promptData[0, i] == data) { results.Add(i); goto ReadNext; } } WriteErrorLine("Invalid choice: " + data); } }