C# console çalışması nasıl belirli bir konumda gösterilir?

Eki Görüntüle 2229536

Buna benzer bir şey mi istiyorsun?
Evet tam bu lakin sormak istediğim sorudan tek farkı Print , clear , exit gibi, ama daha fazla menülerin sayfa içerisinde konumlandırıp kullanıcı hangisine gitmek isterse sağ / sol , aşağı / yukarı olacak şekilde hareket edebilecek. Örn olarak bios ayarlarına girdiğinizde birden fazla menülerin olduğu bir sayfa açılır ve kullanıcı gitmek istediği yere (sağ / sol , aşağı / yukarı) klavyeden ya da mouse ile hareket etmekte.
 
Öylesi daha komplike olur ama yapılamaz değil. Print bastığımda mesela hemen yanına yazıyor şuan, öyle ayarladım. Kodu atayım incele. Daha detaylısını yaparsın.

C#:
class ColoredMenu {
    private ConsoleColor defaultBackColor, defaultForeColor;
    private ConsoleColor BackColor;
    private ConsoleColor ForeColor;
    private string title;
    private List<string> options;
    private int selectedIndex;
    private int Top, Left;
    private bool first_time = true;
    public int SelectedIndex {
        get =>  selectedIndex;
        set => selectedIndex = value;
    }

    public delegate void Event(int id);
    private delegate void Printer();
    public List<Event> SelectedEventHandlers;

    public ColoredMenu(string title, List<string> options, List<Event> SelectedEventHandlers, ConsoleColor higlighted_back = ConsoleColor.Blue, ConsoleColor highlighted_fore = ConsoleColor.White) {
        defaultBackColor = Console.BackgroundColor;
        defaultForeColor = Console.ForegroundColor;

        BackColor = higlighted_back;
        ForeColor = highlighted_fore;

        this.title = title;
        this.options = options;
        selectedIndex = 0;

        this.SelectedEventHandlers = SelectedEventHandlers;
        Top = 0;
        Left = 0;
    }

    public ColoredMenu(string title, List<string> options, ConsoleColor higlighted_back = ConsoleColor.Blue, ConsoleColor highlighted_fore = ConsoleColor.White) {
        defaultBackColor = Console.BackgroundColor;
        defaultForeColor = Console.ForegroundColor;

        BackColor = higlighted_back;
        ForeColor = highlighted_fore;

        this.title = title;
        this.options = options;
        selectedIndex = 0;

        SelectedEventHandlers = [];
        Top = 0;
        Left = 0;
    }

    ~ColoredMenu() {
        Console.CursorVisible = true;
    }


    private void Highlight() {
        Console.BackgroundColor = BackColor;
        Console.ForegroundColor = ForeColor;
    }

    private void DefaultColor() {
        Console.BackgroundColor = defaultBackColor;
        Console.ForegroundColor = defaultForeColor;
    }

    private void PrintlineHighlighted(string option) {
        Highlight();
        Console.WriteLine(" " + option);
        DefaultColor();
    }
    private void PrintHighlighted(string option) {
        Highlight();
        Console.Write(option);
        DefaultColor();
    }
   
    public void PrintMenuSingle() {
        if (options == null) { return; }

        Console.WriteLine(title);

        for(int i = 0; i < options.Count; i++) {
            if(i == selectedIndex) {
                PrintlineHighlighted(options[i]);
                continue;
            }
            Console.WriteLine(" " + options[i]);
        }
    }

    private int GetMax() {
        int max = title.Length;
        foreach(string option in options) {
            max = Math.Max(max, option.Length);
        }
        return max;
    }

    public void PrintMenuAlt() {
        if (options == null) { return; }
        if(first_time) {
            (Left, Top) = Console.GetCursorPosition();
        }

        Console.Write(title);
        Top += 1;
        Left += 1;

        for(int i = 0; i < options.Count; i++) {
            Console.SetCursorPosition(Left, Top);
            if(i == selectedIndex) {
                PrintHighlighted(options[i]);
                Top += 1;
                continue;
            }
            Console.Write(options[i]);
            Top += 1;
        }
        Left -= 1;
        Console.SetCursorPosition(Left, Top);
    }

    private void DecrementSelected() {
        if (selectedIndex - 1 < 0) { return; }
        selectedIndex -= 1;
    }

    private void IncrementSelected() {
        if (selectedIndex + 1 >= options.Count) { return; }
        SelectedIndex += 1;
    }

    private int PrintMenuLoop(Printer Print) {
        while (true) {
            Console.CursorVisible = false;
            Print.Invoke();
            var key = Console.ReadKey(false).Key;
            if(key == ConsoleKey.Enter) {
                Console.CursorVisible = true;
                return selectedIndex;
            }
            if(key == ConsoleKey.UpArrow) {
                DecrementSelected();
            }
            if(key == ConsoleKey.DownArrow) {
                IncrementSelected();
            }
            Clear();
            Console.CursorVisible = true;
        }
    }

    public void PrintMenu() {
        if(SelectedEventHandlers.Count < options.Count) {
            throw new ArgumentOutOfRangeException("You cannot call this function without supplying enough event handlers. \"Try PrintMenuNoHandler()\" instead.");
        }
        int result = PrintMenuLoop(PrintMenuSingle);
        SelectedEventHandlers[result].Invoke(result);
    }

    public void PrintMenuAlternative() {
        if(SelectedEventHandlers.Count < options.Count) {
            throw new ArgumentOutOfRangeException("You cannot call this function without supplying enough event handlers. \"Try PrintMenuNoHandler()\" instead.");
        }
        int result = PrintMenuLoop(PrintMenuAlt);
        SelectedEventHandlers[result].Invoke(result);
    }
   
    public int PrintMenuNoHandler() {
        return PrintMenuLoop(PrintMenuAlt);
    }

    private void ClearNLines(int n) {
        var lastline = Console.GetCursorPosition();
        lastline.Top -= 1;
        Console.SetCursorPosition(0, lastline.Top);
        int max = GetMax();
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < max; j++) {
                Console.Write(" ");
            }
            Console.SetCursorPosition(0, lastline.Top);
            lastline.Top -= 1;
        }
    }

    private void ClearAll(int n) {
        var lastline = Console.GetCursorPosition();
        lastline.Top -= 1;
        Console.SetCursorPosition(0, lastline.Top);
        int max = GetMax();
        for(int i = 0; i < n; i++) {
            for(int j = 0; j < Console.WindowWidth; j++) {
                Console.Write(" ");
            }
            Console.SetCursorPosition(0, lastline.Top);
            lastline.Top -= 1;
        }
    }

    public void Clear() {
        ClearNLines(options.Count + 1);
    }

    public void ClearAll() {
        ClearAll(options.Count + 1);
    }
}

class ConsoleList {
    public static void Print(int left, int top, string title, List<String> list) {
        var initialPos = Console.GetCursorPosition();
        Console.SetCursorPosition(left, top);
        var current = Console.GetCursorPosition();
        Console.Write(title);
        Console.SetCursorPosition(left += 1, current.Top + 1);
        current = Console.GetCursorPosition();
        foreach(var item in list) {
            Console.Write(item);
            Console.SetCursorPosition(left, current.Top + 1);
            current = Console.GetCursorPosition();
        }
        Console.SetCursorPosition(initialPos.Left, top - 1);
    }
}

Örnek kullanımı da şu, attığım gifin kodu;

C#:
string title = "Select an operation: ";

ColoredMenu menu = new ColoredMenu(title, ["Print", "Clear", "Exit"]);

bool run = true;
menu.SelectedEventHandlers = [x => ConsoleList.Print(title.Length + 5, Console.CursorTop - 3, "List", ["Item1", "Long Item 1"]), x => menu.ClearAll(), x => run = false];

while(run) {
    menu.PrintMenuAlternative();
}

menu.Clear();

EventHandlerlar yerine NoHandler versiyonu da var. O da seçilenin index'ini döndürüyor.
 
İlgin için çok teşekkür ederim. Komutları irdeleyeceğim. Lakin rica etsem konuyu anlayabilmem için kaynak sunabilir misiniz ? Yada bunu kavrayabilmem için nasıl bir yol ve konu içeriklerine bakmalıyım ?

Görsel de ki gibi hata vermesindeki sebep version mu? Yoksa başka bir sebep mi ?
 

Dosya Ekleri

  • SharedScreenshot15.jpg
    220,7 KB · Görüntüleme: 21
  • SharedScreenshot16.jpg
    203,2 KB · Görüntüleme: 15
Son düzenleme:
Görsel de ki gibi hata vermesindeki sebep version mu? Yoksa başka bir sebep mi ?
Evet versiyonmus. Ben 8.0'da yazmıştım bunu. Collection express yazan satirlari 7'ye gore duzenleyebilirsin.

İlgin için çok teşekkür ederim. Komutları irdeleyeceğim. Lakin rica etsem konuyu anlayabilmem için kaynak sunabilir misiniz ? Yada bunu kavrayabilmem için nasıl bir yol ve konu içeriklerine bakmalıyım ?
MSDN dokümanları dışında bir seye bakmana gerek yok ya. Ben yazarken dokümandan yararlandım. Cursor movement ile render yapiyorum. Cursor movement ile render yaptığım için daha önce yazdigim/çizdiğim hic bir sey kaybolmuyor. Böylece klavye kontrollü menü elde ederken yanına ekledigim görüntüleme metinleri kaybolmuyor.

Fare desteği nasıl eklersin bil miyorum. Bakmak lazım. Kafana takılan bir şey olursa sor yine.
 
Bu siteyi kullanmak için çerezler gereklidir. Siteyi kullanmaya devam etmek için çerezleri kabul etmelisiniz. Daha Fazlasını Öğren.…