/// <summary> /// /// See base class /// /// </summary> /// <param name="caption"></param> /// <param name="message"></param> /// <param name="choices"></param> /// <param name="defaultChoice"></param> /// <returns></returns> /// <exception cref="ArgumentNullException"> /// /// If <paramref name="choices"/> is null. /// /// </exception> /// <exception cref="ArgumentException"> /// /// If <paramref name="choices"/>.Count is 0. /// /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// /// If <paramref name="defaultChoice"/> is greater than /// the length of <paramref name="choices"/>. /// /// </exception> /// <exception cref="PromptingException"> /// /// when prompt is canceled by, for example, Ctrl-c. /// /// </exception> public override int PromptForChoice(string caption, string message, Collection <ChoiceDescription> choices, int defaultChoice) { HandleThrowOnReadAndPrompt(); if (choices == null) { throw new ArgumentNullException("choices"); } if (choices.Count == 0) { throw new ArgumentException(Util.Sprintf(EmptyChoicesErrorTemplateResource, "choices"), "choices"); } if ((defaultChoice < -1) || (defaultChoice >= choices.Count)) { throw new ArgumentOutOfRangeException("defaultChoice", defaultChoice, Util.Sprintf(InvalidDefaultChoiceErrorTemplateResource, "defaultChoice", "choice")); } // we lock here so that multiple threads won't interleave the various reads and writes here. lock (_instanceLock) { if (!string.IsNullOrEmpty(caption)) { // Should be a skin lookup WriteLineToConsole(); WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption)); WriteLineToConsole(); } if (!string.IsNullOrEmpty(message)) { WriteLineToConsole(WrapToCurrentWindowWidth(message)); } int result = defaultChoice; string[,] hotkeysAndPlainLabels = null; HostUIHelperMethods.BuildHotkeysAndPlainLabels(choices, out hotkeysAndPlainLabels); Dictionary <int, bool> defaultChoiceKeys = new Dictionary <int, bool>(); // add the default choice key only if it is valid. -1 is used to specify // no default. if (defaultChoice >= 0) { defaultChoiceKeys.Add(defaultChoice, true); } do { WriteChoicePrompt(hotkeysAndPlainLabels, defaultChoiceKeys, false); ReadLineResult rlResult; string response = ReadLine(false, "", out rlResult, true, true); if (rlResult == ReadLineResult.endedOnBreak) { string msg = ConsoleHostUserInterfaceStrings.PromptCanceledError; PromptingException e = new PromptingException( msg, null, "PromptForChoiceCanceled", ErrorCategory.OperationStopped); throw e; } if (response.Length == 0) { // they just hit enter. if (defaultChoice >= 0) { // if there's a default, pick that one. result = defaultChoice; break; } continue; } // decide which choice they made. if (response.Trim() == "?") { // show the help ShowChoiceHelp(choices, hotkeysAndPlainLabels); continue; } result = HostUIHelperMethods.DetermineChoicePicked(response.Trim(), choices, hotkeysAndPlainLabels); if (result >= 0) { break; } // their input matched none of the choices, so prompt again }while (true); return(result); } }
/// <summary> /// Presents a dialog allowing the user to choose options from a set of options. /// </summary> /// <param name="caption"> /// Caption to precede or title the prompt. E.g. "Parameters for get-foo (instance 1 of 2)" /// </param> /// <param name="message"> /// A message that describes what the choice is for. /// </param> /// <param name="choices"> /// An Collection of ChoiceDescription objects that describe each choice. /// </param> /// <param name="defaultChoices"> /// The index of the labels in the choices collection element to be presented to the user as /// the default choice(s). /// </param> /// <returns> /// The indices of the choice elements that corresponds to the options selected. /// </returns> /// <seealso cref="System.Management.Automation.Host.PSHostUserInterface.PromptForChoice"/> public Collection <int> PromptForChoice(string caption, string message, Collection <ChoiceDescription> choices, IEnumerable <int> defaultChoices) { HandleThrowOnReadAndPrompt(); if (choices == null) { throw new ArgumentNullException("choices"); } if (choices.Count == 0) { throw new ArgumentException(Util.Sprintf(EmptyChoicesErrorTemplateResource, "choices"), "choices"); } Dictionary <int, bool> defaultChoiceKeys = new Dictionary <int, bool>(); if (null != defaultChoices) { foreach (int defaultChoice in defaultChoices) { if ((defaultChoice < 0) || (defaultChoice >= choices.Count)) { throw new ArgumentOutOfRangeException( "defaultChoice", defaultChoice, Util.Sprintf("\"{0}\" must be a valid index into \"{1}\". \"{2}\" is not a valid index.", "defaultChoice", "choices", defaultChoice)); } if (!defaultChoiceKeys.ContainsKey(defaultChoice)) { defaultChoiceKeys.Add(defaultChoice, true); } } } Collection <int> result = new Collection <int>(); // we lock here so that multiple threads won't interleave the various reads and writes here. lock (_instanceLock) { // write caption on the console, if present. if (!string.IsNullOrEmpty(caption)) { // Should be a skin lookup WriteLineToConsole(); WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(caption)); WriteLineToConsole(); } // write message if (!string.IsNullOrEmpty(message)) { WriteLineToConsole(WrapToCurrentWindowWidth(message)); } string[,] hotkeysAndPlainLabels = null; HostUIHelperMethods.BuildHotkeysAndPlainLabels(choices, out hotkeysAndPlainLabels); WriteChoicePrompt(hotkeysAndPlainLabels, defaultChoiceKeys, true); if (defaultChoiceKeys.Count > 0) { WriteLineToConsole(); } // used to display ChoiceMessage like Choice[0],Choice[1] etc int choicesSelected = 0; do { // write the current prompt string choiceMsg = Util.Sprintf(ConsoleHostUserInterfaceStrings.ChoiceMessage, choicesSelected); WriteToConsole(PromptColor, RawUI.BackgroundColor, WrapToCurrentWindowWidth(choiceMsg)); ReadLineResult rlResult; string response = ReadLine(false, "", out rlResult, true, true); if (rlResult == ReadLineResult.endedOnBreak) { string msg = ConsoleHostUserInterfaceStrings.PromptCanceledError; PromptingException e = new PromptingException( msg, null, "PromptForChoiceCanceled", ErrorCategory.OperationStopped); throw e; } // they just hit enter if (response.Length == 0) { // this may happen when // 1. user wants to go with the defaults // 2. user selected some choices and wanted those // choices to be picked. // user did not pick up any choices..choose the default if ((result.Count == 0) && (defaultChoiceKeys.Keys.Count >= 0)) { // if there's a default, pick that one. foreach (int defaultChoice in defaultChoiceKeys.Keys) { result.Add(defaultChoice); } } // allow for no choice selection. break; } // decide which choice they made. if (response.Trim() == "?") { // show the help ShowChoiceHelp(choices, hotkeysAndPlainLabels); continue; } int choicePicked = HostUIHelperMethods.DetermineChoicePicked(response.Trim(), choices, hotkeysAndPlainLabels); if (choicePicked >= 0) { result.Add(choicePicked); choicesSelected++; } // prompt for multiple choices }while (true); return(result); } }