C#Console始终保持底部的进度条

时间:2016-04-26 14:32:25

标签: c# console cursor progress-bar

我正在做的是将日志文件记录读入控制台。 我想在底部保留一个进度条并显示进度。

问题是:更新记录将覆盖进度条。

        private static void DrawProgressBar(int complete, int maxVal, int barSize, char progressCharacter)
    {
        Console.CursorVisible = false;
        int left = Console.CursorLeft;
        //int top = Console.CursorTop;

        //Console.CursorTop = Console.WindowTop + Console.WindowHeight - 1;

        decimal perc = (decimal)complete / (decimal)maxVal;
        int chars = (int)Math.Floor(perc / ((decimal)1 / (decimal)barSize));
        string p1 = String.Empty, p2 = String.Empty;

        for (int i = 0; i < chars; i++) p1 += progressCharacter;
        for (int i = 0; i < barSize - chars; i++) p2 += progressCharacter;

        Console.ForegroundColor = ConsoleColor.Green;
        Console.Write(p1);
        Console.ForegroundColor = ConsoleColor.DarkGreen;
        Console.Write(p2);

        Console.ResetColor();
        Console.Write(" {0}%", (perc * 100).ToString("N2"));
        Console.CursorLeft = left;
        //Console.SetCursorPosition(left, top);
    }

2 个答案:

答案 0 :(得分:0)

您需要将光标设置到正确的位置。

以下是SetCursorPosition的一个简单示例:

        for (int i = 0; i < 10; i++) {
            Console.SetCursorPosition(0, 0);
            Console.Write("i = {0}", i);
            System.Threading.Thread.Sleep(1000);
        }

在打印进度条之前,您需要在写入进度条之前找到从哪里开始并重置光标。

答案 1 :(得分:0)

有一种简单的方法可以做到这一点以及几种非常困难的方法。

简单的方法是在每次调用Console.WriteLine后重新显示进度条。这样,滚动的行是否会覆盖进度条并不重要,因为您只是要重新显示它。

如果你想获得幻想,你需要自己处理滚动。这意味着创建一个TextWriter后代,看到你写到最后一行(状态行所在的位置),并且,当某些代码想要写入进度条所在的底线时,你滚动其余的屏幕并在空位上写下新线。

第二种方法存在一些问题,第一种方法是为了处理自己的滚动,你必须调用Windows API; .NET BCL中不支持操作控制台屏幕缓冲区。我有你可以使用的代码(参见http://mischel.com/toolutil/consoledotnet.zip),但它有点牵扯。另外,如果您正在编写的行比当前窗口宽度宽,则还有其他问题。如果换行,那么它将覆盖你的进度条。

在每一行之后重新绘制状态栏真的很简单,或者如果你一次写多行就重新绘制一组行。