Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- using System;
- using System.Collections.Generic;
- using System.ComponentModel;
- using System.Linq;
- using System.Reflection;
- using System.Text;
- using System.Text.RegularExpressions;
- // POSTED ONLINE: https://pastebin.com/K4KcHS5u
- namespace ConsoleMenuAdvanced
- {
- internal class Program
- {
- #region Constructors
- private static void Main(string[] args)
- {
- _mainMenu.Show();
- }
- #endregion Constructors
- #region Members
- private static void UpdatePromptStatus()
- {
- _promptMenu.Status = PROMPT_TEXT;
- foreach (string argument in _promptArguments)
- _promptMenu.Status += $" {argument}";
- }
- #endregion Members
- #region Fields
- #region Main menu
- private static ConsoleMenu _mainMenu = new ConsoleMenu("Main Menu:", new JaggedList<ConsoleMenuItem> {
- // Row 0.
- new ConsoleMenuItem("Items", (c, k) => {
- if(k.Key == ConsoleKey.Enter)
- _itemsMenu.Show();
- }),
- // Row 1.
- new ConsoleMenuItem("Options", (c, k) => {
- if(k.Key == ConsoleKey.Enter)
- _optionsMenu.Show();
- }),
- // Row 2.
- new ConsoleMenuItem("Prompt", (c, k) => {
- if(k.Key == ConsoleKey.Enter)
- _promptMenu.Show();
- }),
- // Row 3.
- new ConsoleMenuItem("Exit", (c, k) => {
- if(k.Key == ConsoleKey.Enter)
- {
- Console.WriteLine();
- Environment.Exit(0);
- }
- }),
- });
- #endregion Main menu
- #region Items menu
- private static ConsoleMenu _itemsMenu = new ConsoleMenu("Items Menu:", new Func<JaggedList<ConsoleMenuItem>>(() =>
- {
- JaggedList<ConsoleMenuItem> items = new JaggedList<ConsoleMenuItem>();
- // Row 0.
- items.Add(new ConsoleMenuItem("< Back", (c, k) =>
- {
- if (k.Key == ConsoleKey.Enter)
- {
- _mainMenu.Show();
- _itemsMenu.Status = null;
- }
- }));
- // Row 1.
- items.Add(new ConsoleMenuItem("Add Item", (c, k) =>
- {
- if (k.Key == ConsoleKey.Enter)
- {
- items.Add(new ConsoleMenuItem($"Option {items.Count - 2}", (cc, kk) =>
- {
- if (kk.Key == ConsoleKey.Enter)
- ConsoleMenu.DisplayMessage($"You selected {cc.Text.Trim()}.");
- }));
- }
- }));
- return items;
- })());
- #endregion Items menu
- #region Options menu
- private static ConsoleMenuToggleItem _disableableConsoleMenuToggleItem = new ConsoleMenuToggleItem("Disabled Option", false) { Indent = " ┗━", IsEnabled = false };
- private static ConsoleMenu _optionsMenu = new ConsoleMenu("Options Menu:", new JaggedList<ConsoleMenuItem> {
- // Row 0.
- new ConsoleMenuItem("< Back", (c, k) => {
- if (k.Key == ConsoleKey.Enter)
- _mainMenu.Show();
- }),
- // Row 1.
- {
- new ConsoleMenuToggleItem("Option 1", false, (c,k) => {
- _disableableConsoleMenuToggleItem.IsEnabled = c.IsToggled;
- _disableableConsoleMenuToggleItem.Text = c.IsToggled ? "Enabled Option" : "Disabled Option";
- }),
- new ConsoleMenuToggleItem("Option 2", false)
- },
- // Row 2.
- {
- _disableableConsoleMenuToggleItem
- },
- // Row 3.
- {
- new ConsoleMenuSelectorItem(new[] { "Safe", "ONE", "On" }, 1, (c, k) => {
- for (int i = 0; i < c.Selections.Count; i++)
- if (i == c.SelectedIndex)
- c.Selections[i] = c.Selections[i].ToUpper();
- else
- c.Selections[i] = char.ToUpper(c.Selections[i][0]) + c.Selections[i].Substring(1).ToLower();
- })
- },
- // Row 4.
- {
- new ConsoleMenuValueItem("Letters, numbers, symbols, and punctuation:")
- },
- // Row 5.
- {
- new ConsoleMenuValueItem("Letters and numbers:", new Regex(@"^[a-zA-Z\d\s]*$"))
- },
- // Row 6.
- {
- new ConsoleMenuValueItem("Numbers only:", new Regex(@"^[\d]*$"))
- },
- });
- #endregion Options menu
- #region Prompt menu
- private static ConsoleMenu _promptMenu = new ConsoleMenu("Prompt Menu: (Highlight an entry and press Enter to append and Backspace to delete from the end)", new Func<JaggedList<ConsoleMenuItem>>(() =>
- {
- JaggedList<ConsoleMenuItem> items = new JaggedList<ConsoleMenuItem>();
- // Row 0.
- items.Add(new ConsoleMenuItem("< Back", (c, k) =>
- {
- if (k.Key == ConsoleKey.Enter)
- _mainMenu.Show();
- }));
- #region Generate a square-ish arrangement of rows and columns
- Random random = new Random();
- // Generate names.
- const int ITEMS_COUNT = 23;
- List<string> names = new List<string>(ITEMS_COUNT);
- for (int i = 1; i <= ITEMS_COUNT; i++)
- names.Add($"Item_{random.Next(1, 1000)}");
- int itemsPerRow = (int)Math.Sqrt(ITEMS_COUNT); // Sqrt gives the side-length of a square whose area equals the items count, but conversion to int (or rounding with Math.Floor()) will likely result in a "square-ish" rectangle
- // Depending on the length of each item you might want to clamp the max number of items per row.
- //const int MAX_ITEMS_PER_ROW = 3;
- //ITEMS_PER_ROW = Math.Min(MAX_ITEMS_PER_ROW, ITEMS_PER_ROW);
- List<ConsoleMenuItem> row = new List<ConsoleMenuItem>(itemsPerRow);
- for (int i = 0, j = 0; i < names.Count; i++, j++)
- {
- if (j >= itemsPerRow)
- {
- // Add filled row.
- items.Add(row);
- row = new List<ConsoleMenuItem>(itemsPerRow);
- j = 0;
- }
- row.Add(new ConsoleMenuItem(names[i], (c, k) =>
- {
- switch (k.Key)
- {
- case ConsoleKey.Enter:
- _promptArguments.Add(c.Text);
- UpdatePromptStatus();
- break;
- case ConsoleKey.Backspace:
- if (_promptArguments.Count > 0)
- _promptArguments.RemoveAt(_promptArguments.Count - 1);
- UpdatePromptStatus();
- break;
- }
- }));
- }
- // Add partially filled row.
- items.Add(row);
- #endregion Generate a square-ish arrangement of rows and columns
- // Row N.
- items.Add(new ConsoleMenuItem("Save", (c, k) =>
- {
- switch (k.Key)
- {
- case ConsoleKey.Enter:
- ConsoleMenu.DisplayMessage($"You selected {c.Text.Trim()}.");
- break;
- case ConsoleKey.Backspace:
- if (_promptArguments.Count > 0)
- _promptArguments.RemoveAt(_promptArguments.Count - 1);
- UpdatePromptStatus();
- break;
- }
- }));
- return items;
- })())
- { Status = PROMPT_TEXT };
- private static readonly string PROMPT_TEXT = $"$ {Assembly.GetExecutingAssembly().GetName().Name}.exe";
- private static List<string> _promptArguments = new List<string>();
- #endregion Prompt menu
- #endregion Fields
- }
- public class ConsoleMenu
- {
- #region Properties
- #region Items
- private JaggedList<ConsoleMenuItem> _items;
- public JaggedList<ConsoleMenuItem> Items
- {
- get { return _items; }
- private set
- {
- if (value == null)
- throw new ArgumentNullException(nameof(Items));
- _items = value;
- }
- }
- #endregion Items
- #region SelectedColumn
- private int _selectedColumn = 0;
- public int SelectedColumn
- {
- get
- {
- // Clamp the selected column to allow error-free navigation across uniquely sized rows in the jagged collection.
- _selectedColumn = Math.Max(0, Math.Min(Items[SelectedRow].Count - 1, _selectedColumn));
- return _selectedColumn;
- }
- set
- {
- if (value < 0 ||
- value >= Items[SelectedRow].Count)
- throw new ArgumentOutOfRangeException(nameof(SelectedColumn), $"Value '{value}' must be in the range [{0}, {Items[SelectedRow].Count - 1}].");
- _selectedColumn = value;
- }
- }
- #endregion SelectedColumn
- #region SelectedRow
- private int _selectedRow = 0;
- public int SelectedRow
- {
- get
- {
- // Clamp the selected row in case the collection was modified.
- _selectedRow = Math.Max(0, Math.Min(Items.Count - 1, _selectedRow));
- return _selectedRow;
- }
- set
- {
- if (value < 0 ||
- value >= Items.Count)
- throw new ArgumentOutOfRangeException(nameof(SelectedRow), $"Value '{value}' must be in the range [{0}, {Items.Count - 1}].");
- _selectedRow = value;
- }
- }
- #endregion SelectedRow
- #region SelectedItem
- public ConsoleMenuItem SelectedItem
- {
- get
- {
- if (Items.Count == 0)
- return null;
- return Items[SelectedRow][SelectedColumn];
- }
- }
- #endregion SelectedItem
- #region Status
- public string Status { get; set; } = null;
- #endregion Status
- #region Title
- public string Title { get; set; }
- #endregion Title
- #region LeftPadding
- public string LeftPadding { get; set; } = " ";
- #endregion LeftPadding
- #region RightPadding
- public string RightPadding { get; set; } = " ";
- #endregion RightPadding
- #endregion Properties
- #region Events
- #region ConsoleKeyEvent
- public event EventHandler<ConsoleKeyEventArgs> ConsoleKeyEvent;
- protected virtual void OnConsoleKeyEvent(ConsoleKeyEventArgs e)
- {
- if (e == null)
- throw new ArgumentNullException(nameof(e));
- ConsoleKeyEvent?.Invoke(this, e);
- }
- #endregion ConsoleKeyEvent
- #region PreConsoleKeyEvent
- public event EventHandler<PreConsoleKeyEventArgs> PreConsoleKeyEvent;
- protected virtual bool OnPreConsoleKeyEvent(PreConsoleKeyEventArgs e)
- {
- if (e == null)
- throw new ArgumentNullException(nameof(e));
- PreConsoleKeyEvent?.Invoke(this, e);
- return e.Cancel;
- }
- #endregion PreConsoleKeyEvent
- #endregion Events
- #region Constructors
- static ConsoleMenu()
- {
- // Hide the cursor since its confusing to see when entering input to a field that isn't on the last line of the console output.
- Console.CursorVisible = false;
- // Enable Unicode output so we can display box-drawing characters.
- Console.OutputEncoding = Encoding.UTF8;
- }
- public ConsoleMenu(string title)
- : this(title, new JaggedList<ConsoleMenuItem>())
- {
- }
- public ConsoleMenu(string title, JaggedList<ConsoleMenuItem> items)
- {
- Title = title;
- Items = items;
- }
- #endregion Constructors
- #region Members
- /// <summary>
- /// Display the menu.
- /// </summary>
- public void Show()
- {
- if (_currentMenu != this)
- {
- bool firstRun = _currentMenu == null;
- _currentMenu = this;
- if (firstRun == false) // If a menu-drawing loop is running.
- return;
- }
- while (true)
- {
- DrawMenu(_currentMenu);
- ProcessKeyboardInput(_currentMenu);
- }
- }
- /// <summary>
- /// Display a message to the user and pause the menu loop.
- /// </summary>
- /// <param name="value">The <see cref="string"/> to display.</param>
- /// <exception cref="ArgumentNullException"></exception>
- public static void DisplayMessage(string value)
- {
- if (string.IsNullOrEmpty(value))
- throw new ArgumentNullException(nameof(value));
- if (_currentMenu == null)
- return;
- Console.Write($"{Environment.NewLine}{Environment.NewLine}{_currentMenu.LeftPadding}{_currentMenu.LeftPadding}{value}");
- Pause();
- }
- /// <summary>
- /// Pause the menu loop.
- /// </summary>
- public static void Pause()
- {
- if (_currentMenu == null)
- return;
- Console.Write($"{Environment.NewLine}{Environment.NewLine}{_currentMenu.LeftPadding}{_currentMenu.LeftPadding}Press any key to continue . . . ");
- Console.ReadKey();
- }
- /// <summary>
- /// Draw menu title and items.
- /// </summary>
- /// <param name="menu">The <see cref="ConsoleMenu"/> to draw.</param>
- /// <exception cref="ArgumentNullException"></exception>
- private static void DrawMenu(ConsoleMenu menu)
- {
- if (menu == null)
- throw new ArgumentNullException(nameof(menu));
- Console.Clear();
- #region Draw title
- if (string.IsNullOrEmpty(menu.Title) == false)
- Console.WriteLine($"{menu.LeftPadding}{menu.Title}{menu.LeftPadding}");
- #endregion Draw title
- #region Measure horizontal items
- int largestConsoleMenuItemTextLength = 0;
- for (int row = 0; row < menu.Items.Count; row++)
- {
- int columnsCount = menu.Items[row].Count;
- if (columnsCount == 1) // If only one item in this row.
- continue;
- for (int column = 0; column < columnsCount; column++)
- {
- ConsoleMenuItem item = menu.Items[row][column];
- largestConsoleMenuItemTextLength = Math.Max(largestConsoleMenuItemTextLength, item.Text.Length);
- }
- }
- #endregion Measure horizontal items
- #region Draw items
- for (int row = 0; row < menu.Items.Count; row++)
- {
- int columnsCount = menu.Items[row].Count;
- for (int column = 0; column < columnsCount; column++)
- {
- ConsoleMenuItem consoleMenuItem = menu.Items[row][column];
- if (consoleMenuItem == null)
- throw new NullReferenceException($"Null {nameof(ConsoleMenuItem)} detected.");
- string rowIndent;
- if (row == 0)
- rowIndent = menu.LeftPadding; // Has the affect of 2x left-padding indent.
- else if (column == 0)
- rowIndent = $"{Environment.NewLine}{menu.LeftPadding}"; // Has the affect of 2x left-padding indent.
- else // If a horizontal item.
- rowIndent = null;
- Console.Write(rowIndent);
- Console.Write(consoleMenuItem.Indent);
- bool isSelected = (row == menu.SelectedRow && column == menu.SelectedColumn);
- if (isSelected)
- {
- // Apply selected item colors.
- if (consoleMenuItem.IsEnabled)
- {
- if (consoleMenuItem.IsError)
- {
- Console.ForegroundColor = ConsoleColor.Black;
- Console.BackgroundColor = ConsoleColor.DarkRed;
- }
- else
- {
- Console.ForegroundColor = ConsoleColor.Black;
- Console.BackgroundColor = ConsoleColor.White;
- }
- }
- else
- {
- Console.ForegroundColor = ConsoleColor.Black;
- Console.BackgroundColor = ConsoleColor.DarkYellow;
- }
- }
- else
- {
- // Apply selected item colors.
- if (consoleMenuItem.IsEnabled)
- {
- if (consoleMenuItem.IsError)
- {
- Console.ForegroundColor = ConsoleColor.DarkRed;
- Console.BackgroundColor = ConsoleColor.Black;
- }
- else
- {
- Console.ForegroundColor = ConsoleColor.White;
- Console.BackgroundColor = ConsoleColor.Black;
- }
- }
- else
- {
- Console.ForegroundColor = ConsoleColor.DarkYellow;
- Console.BackgroundColor = ConsoleColor.Black;
- }
- }
- Console.Write($"{menu.LeftPadding}{consoleMenuItem}{menu.RightPadding}");
- Console.ResetColor();
- if (columnsCount > 1)
- {
- string consoleMenuItemOutdent = new string(' ', largestConsoleMenuItemTextLength - consoleMenuItem.Text.Length);
- Console.Write(consoleMenuItemOutdent);
- }
- }
- }
- #endregion Draw items
- #region Draw status
- if (string.IsNullOrEmpty(menu.Status) == false)
- Console.Write($"{Environment.NewLine}{Environment.NewLine}{menu.LeftPadding}{menu.LeftPadding}{menu.Status}");
- #endregion Draw status
- }
- /// <summary>
- /// Navigate and execute menu items based on keyboard input.
- /// </summary>
- /// <param name="menu"></param>
- /// <exception cref="ArgumentNullException"></exception>
- private static void ProcessKeyboardInput(ConsoleMenu menu)
- {
- if (menu == null)
- throw new ArgumentNullException(nameof(menu));
- ConsoleKeyInfo consoleKeyInfo = Console.ReadKey(true); // True to not display the pressed key.
- bool cancel = menu.OnPreConsoleKeyEvent(new PreConsoleKeyEventArgs(menu.SelectedItem, consoleKeyInfo));
- if (cancel)
- return;
- int rows = menu.Items.Count;
- if (rows == 0)
- return;
- int columns = menu.Items[menu.SelectedRow].Count;
- switch (consoleKeyInfo.Key)
- {
- case ConsoleKey.UpArrow:
- // Loop around backwards.
- menu.SelectedRow = (menu.SelectedRow - 1 + rows) % rows;
- break;
- case ConsoleKey.DownArrow:
- // Loop around forwards.
- menu.SelectedRow = (menu.SelectedRow + 1) % rows;
- break;
- case ConsoleKey.LeftArrow:
- // Loop around backwards.
- menu.SelectedColumn = (menu.SelectedColumn - 1 + columns) % columns;
- break;
- case ConsoleKey.RightArrow:
- // Loop around forwards.
- menu.SelectedColumn = (menu.SelectedColumn + 1) % columns;
- break;
- default:
- menu.SelectedItem.OnExecute(consoleKeyInfo);
- break;
- }
- menu.OnConsoleKeyEvent(new ConsoleKeyEventArgs(menu.SelectedItem, consoleKeyInfo));
- }
- #endregion Members
- #region Fields
- private static ConsoleMenu _currentMenu = null;
- #endregion Fields
- }
- #region Types
- public class ConsoleMenuValueItem : ConsoleMenuItem
- {
- #region Properties
- #region Filter
- private Regex _filter = null;
- public Regex Filter
- {
- get { return _filter; }
- set
- {
- _filter = value;
- UpdateIsError();
- }
- }
- #endregion Filter
- #region Value
- private string _value = null;
- public string Value
- {
- get { return IsError ? null : _value; }
- set
- {
- _value = value;
- UpdateIsError();
- }
- }
- #endregion Value
- #endregion Properties
- #region Constructors
- public ConsoleMenuValueItem(string text)
- : this(text, null)
- {
- }
- public ConsoleMenuValueItem(string text, Regex filter)
- : this(text, filter, null)
- {
- }
- public ConsoleMenuValueItem(string text, Regex filter, string value)
- : this(text, filter, value, null)
- {
- }
- public ConsoleMenuValueItem(string text, Regex filter, string value, Action<ConsoleMenuValueItem, ConsoleKeyInfo> code)
- : base(text, WrapCode(code))
- {
- Filter = filter;
- Value = value;
- }
- #endregion Constructors
- #region Overrides
- /// <summary>
- /// Execute menu item code.
- /// </summary>
- /// <param name="consoleKeyInfo"></param>
- public override void OnExecute(ConsoleKeyInfo consoleKeyInfo)
- {
- switch (consoleKeyInfo.Key)
- {
- case ConsoleKey.Backspace:
- if (string.IsNullOrEmpty(_value) == false)
- _value = _value.Remove(_value.Length - 1);
- break;
- default:
- char character = consoleKeyInfo.KeyChar;
- if (char.IsControl(character) == false ||
- consoleKeyInfo.Key == ConsoleKey.Tab)
- _value += (consoleKeyInfo.Key == ConsoleKey.Tab) ? " " : character.ToString();
- break;
- }
- UpdateIsError();
- base.OnExecute(consoleKeyInfo);
- }
- public override string ToString()
- {
- string errorMessage = IsError && Filter != null ? $" <-- Does not match pattern: {Filter}" : null;
- return $"{Text ?? base.ToString()}{(string.IsNullOrEmpty(_value) ? null : " ")}{_value}{errorMessage}";
- }
- #endregion Overrides
- #region Members
- private void UpdateIsError()
- {
- IsError = _value != null && _filter?.IsMatch(_value) == false;
- }
- #endregion Members
- }
- public class ConsoleMenuSelectorItem : ConsoleMenuItem
- {
- #region Properties
- #region SelectedIndex
- private int _selectedIndex;
- public int SelectedIndex
- {
- get { return _selectedIndex; }
- set
- {
- if (value < 0 || value >= Selections.Count)
- throw new ArgumentOutOfRangeException(nameof(SelectedIndex));
- _selectedIndex = value;
- }
- }
- #endregion SelectedIndex
- #region Selections
- public List<string> Selections { get; }
- #endregion Selections
- #endregion Properties
- #region Constructors
- public ConsoleMenuSelectorItem(string[] selections)
- : this(selections, 0)
- {
- }
- public ConsoleMenuSelectorItem(string[] selections, int selectedIndex)
- : this(selections, selectedIndex, null)
- {
- }
- public ConsoleMenuSelectorItem(string[] selections, int selectedIndex, Action<ConsoleMenuSelectorItem, ConsoleKeyInfo> code)
- : base(null, WrapCode(code))
- {
- if (selections == null)
- throw new ArgumentNullException(nameof(selections));
- Selections = selections.ToList();
- SelectedIndex = selectedIndex;
- }
- #endregion Constructors
- #region Overrides
- /// <summary>
- /// Execute menu item code.
- /// </summary>
- /// <param name="consoleKeyInfo"></param>
- public override void OnExecute(ConsoleKeyInfo consoleKeyInfo)
- {
- if (consoleKeyInfo.Key == ConsoleKey.Enter)
- Toggle();
- base.OnExecute(consoleKeyInfo);
- }
- public override string ToString()
- {
- return string.Join(" ", Selections.Select((value, index) => (index == SelectedIndex) ? $"[{value}]" : value));
- }
- #endregion Overrides
- #region Members
- /// <summary>
- /// Toggle menu item state.
- /// </summary>
- public void Toggle()
- {
- if (IsEnabled &&
- Selections.Count > 0)
- SelectedIndex = (SelectedIndex + 1) % Selections.Count; // Loop around forwards.
- }
- #endregion Members
- }
- public class ConsoleMenuToggleItem : ConsoleMenuItem
- {
- #region Properties
- #region IsToggled
- private bool _isToggled = false;
- public bool IsToggled
- {
- get { return _isToggled; }
- set
- {
- if (IsEnabled)
- _isToggled = value;
- }
- }
- #endregion IsToggled
- #endregion Properties
- #region Constructors
- public ConsoleMenuToggleItem(string text, bool isToggled)
- : this(text, isToggled, null)
- {
- }
- public ConsoleMenuToggleItem(string text, bool isToggled, Action<ConsoleMenuToggleItem, ConsoleKeyInfo> code)
- : base(text, WrapCode(code))
- {
- IsToggled = isToggled;
- }
- #endregion Constructors
- #region Overrides
- /// <summary>
- /// Execute menu item code.
- /// </summary>
- /// <param name="consoleKeyInfo"></param>
- public override void OnExecute(ConsoleKeyInfo consoleKeyInfo)
- {
- if (consoleKeyInfo.Key == ConsoleKey.Enter)
- Toggle();
- base.OnExecute(consoleKeyInfo);
- }
- public override string ToString()
- {
- return $"{Text ?? base.ToString()} [{(IsToggled ? 'x' : ' ')}]";
- }
- #endregion Overrides
- #region Members
- /// <summary>
- /// Toggle menu item state.
- /// </summary>
- public void Toggle()
- {
- IsToggled ^= true;
- }
- #endregion Members
- }
- public class ConsoleMenuItem
- {
- #region Properties
- #region Code
- public Action<ConsoleMenuItem, ConsoleKeyInfo> Code { get; set; }
- #endregion Code
- #region Indent
- public string Indent { get; set; } = null;
- #endregion Indent
- #region IsEnabled
- public bool IsEnabled { get; set; } = true;
- #endregion IsEnabled
- #region IsError
- public bool IsError { get; set; }
- #endregion IsError
- #region Tag
- public object Tag { get; set; } = null;
- #endregion Tag
- #region Text
- public string Text { get; set; }
- #endregion Text
- #endregion Properties
- #region Constructors
- public ConsoleMenuItem()
- {
- }
- public ConsoleMenuItem(string text)
- : this(text, null)
- {
- }
- public ConsoleMenuItem(string text, Action<ConsoleMenuItem, ConsoleKeyInfo> code)
- {
- Text = text;
- Code = code;
- }
- #endregion Constructors
- #region Overrides
- public override string ToString()
- {
- return Text ?? base.ToString();
- }
- #endregion Overrides
- #region Members
- /// <summary>
- /// Execute menu item code.
- /// </summary>
- /// <param name="consoleKeyInfo"></param>
- public virtual void OnExecute(ConsoleKeyInfo consoleKeyInfo)
- {
- Code?.Invoke(this, consoleKeyInfo);
- }
- protected static Action<ConsoleMenuItem, ConsoleKeyInfo> WrapCode<T>(Action<T, ConsoleKeyInfo> code)
- where T : ConsoleMenuItem
- {
- if (code == null)
- return null;
- return (c, k) => code((T)c, k);
- }
- #endregion Members
- }
- public class ConsoleKeyEventArgs : EventArgs
- {
- #region Properties
- public ConsoleMenuItem ConsoleMenuItem { get; private set; }
- public ConsoleKeyInfo ConsoleKeyInfo { get; private set; }
- #endregion Properties
- #region Constructors
- public ConsoleKeyEventArgs(ConsoleMenuItem consoleMenuItem, ConsoleKeyInfo consoleKeyInfo)
- {
- if (consoleMenuItem == null)
- throw new ArgumentNullException(nameof(consoleMenuItem));
- if (consoleKeyInfo == null)
- throw new ArgumentNullException(nameof(consoleKeyInfo));
- ConsoleKeyInfo = consoleKeyInfo;
- ConsoleMenuItem = consoleMenuItem;
- }
- #endregion Constructors
- }
- public class PreConsoleKeyEventArgs : CancelEventArgs
- {
- #region Properties
- public ConsoleMenuItem ConsoleMenuItem { get; private set; }
- public ConsoleKeyInfo ConsoleKeyInfo { get; private set; }
- #endregion Properties
- #region Constructors
- public PreConsoleKeyEventArgs(ConsoleMenuItem consoleMenuItem, ConsoleKeyInfo consoleKeyInfo)
- {
- if (consoleMenuItem == null)
- throw new ArgumentNullException(nameof(consoleMenuItem));
- if (consoleKeyInfo == null)
- throw new ArgumentNullException(nameof(consoleKeyInfo));
- ConsoleKeyInfo = consoleKeyInfo;
- ConsoleMenuItem = consoleMenuItem;
- }
- #endregion Constructors
- }
- public class JaggedList<T> : List<List<T>>
- {
- #region Members
- /// <summary>
- /// Add a variable-length array of <see cref="T"/> items to the end of the <see cref="JaggedList{T}"/>.
- /// </summary>
- /// <param name="items">A variable-length array of <see cref="T"/> items.</param>
- /// <example>
- /// JaggedList<int> jaggedList = new JaggedList<int> {
- /// 1,
- /// { 2, 3 },
- /// { 5 },
- /// };
- /// jaggedList.Add(6);
- /// jaggedList.Add(7, 8);
- /// jaggedList.Add(new int[] { 9, 10, 11 });
- /// </example>
- public void Add(params T[] items)
- {
- Add(new List<T>(items));
- }
- /// <summary>
- /// Searches for the specified <see cref="T"/> item and returns a tuple containing the zero-based row and column of the first occurrence of the value within the entire <see cref="JaggedList{T}"/>.
- /// </summary>
- /// <param name="value">The object to locate in the <see cref="JaggedList{T}"/>. The value can be null for reference types.</param>
- /// <returns>A tuple containing the zero-based row and column of the first occurrence of the value within the entire <see cref="JaggedList{T}"/> if found, otherwise null.</returns>
- public (int row, int column)? IndexOf(T value)
- {
- for (int row = 0, column; row < Count; row++)
- {
- for (column = 0; column < this[row].Count; column++)
- {
- T item = this[row][column];
- if ((item == null && value == null) ||
- (item != null && item.Equals(value)))
- return (row, column);
- }
- }
- return null;
- }
- #endregion Members
- }
- #endregion Types
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement