如何使文本在C#控制台应用程序中闪烁

时间:2013-06-11 09:57:59

标签: c#

我是C#的新手

我有这个代码

    FileStream D = new FileStream("C:/PersonalAssistant/RecentMeetingDetails.txt", FileMode.Open, FileAccess.Read);
    StreamReader DR = new StreamReader(D);
    DR.BaseStream.Seek(0, SeekOrigin.Begin);

    Console.ForegroundColor = ConsoleColor.Red;
    Console.WriteLine("ALERT! ALERT!! ALERT!!!");
    Console.WriteLine("\nYour Closest Appointment is on " + rd + " and has the following info");

    string data = DR.ReadLine();
    while (data != null)
    {
         Console.WriteLine(data);
         data = DR.ReadLine();
    }
    D.Close();
    DR.Close();

我想要这段代码

    Console.WriteLine("ALERT! ALERT!! ALERT!!!");

在从文件中读取并显示在屏幕上的其他详细信息时闪烁

我试过这个

   private static void WriteBlinkingText(string text, int delay)
   {
        bool visible = true;
        while (true)
        {
            Console.Write("\r" + (visible ? text : new String(' ', text.Length)));
            System.Threading.Thread.Sleep(delay);
            visible = !visible;
        }
   } 

并将console.writeline更改为

    WriteBlinkingText("ALERT! ALERT!! ALERT!!!",500);

它有效但其他细节没有显示......

请帮我纠正这段代码

5 个答案:

答案 0 :(得分:4)

根本原因:

  • 实际上,您只需一个Thread处理所有内容。
  • 线程被无限循环阻塞,即while(true) {... }方法内WriteBlinkingText()

<强>解决方案

创建一个单独的线程来处理闪烁的文本。虽然您的Main Thread将继续执行其余的代码。

答案 1 :(得分:3)

我想你正在寻找这个:

bool visible = true;
do
{
    //Press Ctrl + C to Quit
    string alert = visible ? "ALERT! ALERT!! ALERT!!!" : "";
    visible = !visible;
    Console.Clear();
    string details = File.ReadAllText(@"C:\PersonalAssistant\RecentMeetingDetails.txt");
    Console.Write("{0}\n{1}", alert, details);
    Thread.Sleep(100);
} while (true);

或实现 WHITE TO RED 闪烁

bool visible = true;
do
{
    //Press Ctrl + C to Quit
    string alert = "ALERT! ALERT!! ALERT!!!";
    Console.ForegroundColor = visible ? ConsoleColor.Red : ConsoleColor.White;
    visible = !visible;
    Console.Clear();
    string details = @"C:\PersonalAssistant\RecentMeetingDetails.txt";
    Console.WriteLine(alert);
    Console.ForegroundColor = ConsoleColor.White;
    Console.WriteLine(details);
    Thread.Sleep(100);
} while (true);

您可以轻松地将其重构为方法:

private static void Blinker(string text, int milliseconds)
{
    bool visible = true;
    while(true)
    {
        //Press Ctrl + C to Quit
        string alert = visible ? "ALERT! ALERT!! ALERT!!!" : "";
        visible = !visible;
        Console.Clear();
        string details = File.ReadAllText(@"C:\PersonalAssistant\RecentMeetingDetails.txt");
        Console.Write("{0}\n{1}", alert, details);
        Thread.Sleep(milliseconds);
    }
}

答案 2 :(得分:2)

很抱歉这样说但闪烁的文字可能不适合使用控制台应用程序。

控制台不支持此功能,因此您必须自己实现。由于控制台只会写入光标所在的位置,因此您必须继续将光标移回警报的开头!写出你想要的东西然后把它移回原处。这不会很漂亮。

如果您确实想要这样做,最好的方法是使用计时器(System.Threading.Timer)。计时器将允许应用程序的其余部分在更改闪烁文本之间运行。发生计时器事件时,您需要保存光标位置,移动到警报文本,写入或空白,然后将光标设置回保存位置。当你这样做时,你需要找到一些阻止文件写入的方法,这样你就不会在“Alert!Alert!Alert!”中写下大量的文件。应该。

最后应该注意的是,对于决定将应用程序的输出管道传输到如下文件的人来说,这种技术会非常奇怪:C:&gt; MyApplication.exe&gt; output.txt的

这样的事情应该这样做:

class Program
{
  static System.Threading.Timer timer = new Timer(TimerCallback, null, System.Threading.Timeout.Infinite, 0);
  static int alertX;
  static int alertY;
  static bool alertDisplayed = false;
  static int cursorX;
  static int cursorY;
  static object consoleLock = new object();

  static void Main(string[] args)
  {
     FileStream D = new FileStream("C:/PersonalAssistant/RecentMeetingDetails.txt", FileMode.Open, FileAccess.Read);
     StreamReader DR = new StreamReader(D);
     DR.BaseStream.Seek(0, SeekOrigin.Begin);

     Console.ForegroundColor = ConsoleColor.Red;
     WriteFlashingText();
     lock (consoleLock)
     {
        Console.WriteLine("\nYour Closest Appointment is on " + rd + " and has the following info");
     }

     string data = DR.ReadLine();
     while (data != null)
     {
        lock (consoleLock)
        {
           Console.WriteLine(data);
        }
        data = DR.ReadLine();
     }
     D.Close();
     DR.Close();
  }

  static void WriteFlashingText()
  {
     alertX = Console.CursorLeft;
     alertY = Console.CursorTop;
     timer.Change(0, 200);
  }

  static void TimerCallback(object state)
  {
     lock (consoleLock)
     {
        cursorX = Console.CursorLeft;
        cursorY = Console.CursorTop;

        Console.CursorLeft = alertX;
        Console.CursorTop = alertY;

        if (alertDisplayed)
        {
           Console.WriteLine("Alert! Alert! Alert!");
        }
        else
        {
           Console.WriteLine("                    ");
        }
        alertDisplayed = !alertDisplayed;

        Console.CursorLeft = cursorX;
        Console.CursorTop = cursorY;
     }
  }
}

答案 3 :(得分:0)

class Program {
    static void Main(string[] args) {
        blinkText t = new blinkText("TestTestTest", 500); //new blinkText object
        t.start(); //start blinking

        Thread.Sleep(5000); //Do your work here

        t.stop(); //When your work is finished, call stop() to stop the blinking text blinking

        Console.ReadKey();
    }
}

public class blinkText {
    public blinkText(string text, int delay) {
        this.text = text;
        this.delay = delay;
        this.startLine = Console.CursorTop; //line number of the begin of the text
        this.startColumn = Console.CursorLeft; //column number of the begin of the text
        Console.Write(this.text);
        visible = true;
    }
    public string text;
    public int delay;
    int startLine;
    int startColumn;

    bool visible;

    Timer t;

    public void start() {
        t = new Timer(delegate { //Timer to do work async
            int oldCursorX = Console.CursorLeft; //Save cursor position
            int oldCursorY = Console.CursorTop;  //to restore them later
            Console.CursorLeft = startLine; //change cursor position to
            Console.CursorTop = startColumn; //the begin of the text
            visible = !visible;
            if (visible) {
                Console.Write(text); //write text (overwrites the whitespaces)
            } else {
                ConsoleColor oldColor = Console.ForegroundColor; //change fore color to back color
                Console.ForegroundColor = Console.BackgroundColor; //(makes text invisible)
                Console.Write(text); //write invisible text(overwrites visible text)
                Console.ForegroundColor = oldColor; //restore the old color(makes text visible)
            }
            Console.CursorLeft = oldCursorX; //restore cursor position
            Console.CursorTop = oldCursorY;
        });
        t.Change(0, this.delay); //start timer
    }

    public void stop() {
        t.Change(0, -1); //stop timer
        int oldCursorX = Console.CursorLeft;
        int oldCursorY = Console.CursorTop;
        Console.CursorLeft = startLine;
        Console.CursorTop = startColumn;
        Console.Write(text); //display text visible
        Console.CursorLeft = oldCursorX;
        Console.CursorTop = oldCursorY;
        visible = true;
    }
}

我编辑了答案。现在我创建了一个调用异步计时器的类来使文本闪烁。所以这不会阻止你的程序。为了表明这一点,我在文本开始闪烁后做了Thread.Sleep(5000)。这可能是您需要一段时间才能完成的代码。然后文本结束闪烁。

答案 4 :(得分:-1)

最容易但是杂乱无章的方式是:

static void Blink()
{
    Console.Clear();
        string name = "Your Text";
        Console.WriteLine(name);
        Thread.Sleep(500); //Break
        Console.Clear();
        Thread.Sleep(500);
        Console.WriteLine(name);
        Thread.Sleep(500);
        Console.Clear();
        Thread.Sleep(500);
        Console.WriteLine(name);
        Thread.Sleep(500);
        Console.Clear();
        Thread.Sleep(500);
        Console.WriteLine(name);
        Thread.Sleep(500);
        Console.Clear();
        Thread.Sleep(500);
        Console.WriteLine(name);
        Thread.Sleep(500);
        Console.ReadKey();
}