Меню дисков для консольного файлового менеджера

Пытаюсь реализовать свой файл менеджер. У меня есть List, в котором хранятся объекты DriveInfo.

int top = 1;
DriveInfo[] drives = DriveInfo.GetDrives();
 
List<string> list = drives.Select(x => x.RootDirectory.FullName).ToList();
 
foreach(var disk in list)
{
   Console.SetCursorPosition(2, top);
   Console.WriteLine(disk);
   top++;
}

Мне нужно, чтобы при запуске изменялся цвет background'а первого элемента, чтобы потом я мог стрелками переходить по элементам. Никак не могу уловить логику. Кому не тяжело подтолкните на мысль.


Ответы (1 шт):

Автор решения: aepot

Без использования ООП на полную катушку вы погибнете в сражении с собственнвм кодом раньше, чем напишете что-либо вменяемое. Вот пример, написанный прямо с телефона на коленке, оцените простоту.

Во-первых, вам очень много придется работать с координатами вывода в консоли. Заведите структуру, которая позволит облегчить этот процесс.

public struct Point
{
    public int X { get; }
    public int Y { get; }

    public Point(int x, int y)
    {
        X = x;
        Y = y;
    }
}

Всегда создавайте необходимые структуры данных

public class DrivesMenu
{
    private readonly Point _position;
    private readonly List<string> _drives;
    private int _selectedIndex;

    public string Drive => _drives[_selectedIndex];

    public DrivesMenu(Point position, List<string> drives)
    {
        _position = position;
        _drives = drives;
    }

    public void Draw()
    {
        Point backupPos = new Point(Console.CursorLeft, Console.CursorTop);
        Console.SetCursorPosition(position.X, position.Y);
        for (int i = 0; i < _drives.Count; i++)
        {
            Console.ForegroudColor = i == _selectedIndex ? ConsoleColor.Green : ConsoleColor.White;
            Conosole.Write(_drives[i] + " ");
        }
        Console.ResetColor();
        Console.SetCursorPosition(backupPos.X, backupPos.Y);
    }

    public Next()
    {
        _selectedIndex = (_selectedIndex + 1) % _drives.Count;
        Draw();
    }

    public Previous()
    {
        _selectedIndex = _selectedIndex == 0 ? _drives.Count - 1 : _selectedIndex - 1;
        Draw();
    }

    public SetIndex(int index)
    {
        _selectedIndex = Math.Clamp(index, 0, _drives.Count - 1);
        Draw();
    }

    public SetDrive(string drive)
    {
        SetIndex(_drives.IndexOf(drive));
    }
}

При этом, создайте отдельный файл DrivesMenu.cs в проекте, и поместите этот класс туда. Тогда оно не будет мешаться в основном коде.

Я понаписал методов больше, чем нужно, выберите нужные и уберите лишние, если требуется.

var menu = new DrivesMenu(new Point(10, 10), list);
menu.Draw();

Ну и все остальные компоненты вашего интерфейса можно реализовать подобным образом.

Стрелками переходить очень просто

while (true)
{
    var keyInfo = Console.ReadKey(true);
    if (keyInfo.Key == ConsoleKey.Escape)
        break;
    switch (keyInfo.Key)
    {
        case ConsoleKey.Right:
            menu.Next();
            break;
        case ConsoleKey.Left:
            menu.Previous();
            break;
    }
}
→ Ссылка