Search code examples
c#http-redirectconsoleio

split a console in two parts for two outputs


I'm creating a console application where I would like to have two outputs and one input. The reason would be so that one output is always visible.

This is the first output
Text flows upwards just like a regular console application, however...

---------
This is a second output
This is placed at the bottom of the console // also input goes here.

I was thinking of calling it something like this

 Console.Out.Writeline("This is the first output");
 Console.Out.Writeline("Text flows upwards just like a regular console application, however...");
 MyTextWriter.WriteLine("This is a second output");
 MyTextWriter.WriteLine("This is placed at the bottom of the console");

But how would I go about splitting the console in two parts? Is it even possible?


Solution

  • If I understand you correctly you can use Console.SetCursorPosition to draw text where you want it. Here's a crude example that split the console in two areas with text flowing upward when added to them.

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    
    namespace ConsoleApplication1
    {
        class Program
        {
            static List<string> area1 = new List<string>();
            static List<string> area2 = new List<string>();
            static int areaHeights = 0;
    
            static void Main(string[] args)
            {
                // Number of rows for each area
                areaHeights = (Console.WindowHeight - 2) / 2;
    
                drawScreen();
    
                int i = 0;
                while (true)
                {
                    i++;
    
                    // jumb between areas
                    if (i % 2 == 0)
                        AddLineToBuffer(ref area1, Console.ReadLine());
                    else
                        AddLineToBuffer(ref area2, Console.ReadLine());
    
                    drawScreen();
                }
            }
    
            private static void AddLineToBuffer(ref List<string> areaBuffer, string line)
            {
                areaBuffer.Insert(0, line);
    
                if (areaBuffer.Count == areaHeights)
                {
                    areaBuffer.RemoveAt(areaHeights - 1);
                }
            }
    
    
            private static void drawScreen()
            {
                Console.Clear();
    
                // Draw the area divider
                for (int i = 0; i < Console.BufferWidth; i++)
                {
                    Console.SetCursorPosition(i, areaHeights);
                    Console.Write('=');
                }
    
                int currentLine = areaHeights - 1;
    
                for (int i = 0; i < area1.Count; i++)
                {
                    Console.SetCursorPosition(0, currentLine - (i + 1));
                    Console.WriteLine(area1[i]);
    
                }
    
                currentLine = (areaHeights * 2);
                for(int i = 0; i < area2.Count; i++)
                {
                    Console.SetCursorPosition(0, currentLine - (i + 1));
                    Console.WriteLine(area2[i]);
                }
    
                Console.SetCursorPosition(0, Console.WindowHeight - 1);
                Console.Write("> ");
    
            }
    
        }
    }
    

    I assume you want to fill each area not only with user input? If so you need to set up the drawing of the console in a separate thread and let that thread update the screen when needed.