user2399866
user2399866

Reputation:

How a make a text blink in C# Console Application

I'm a newbie in C#

I have this Code

    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();

I want this code

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

to be blinking while the other details are being read from the file and displayed on the screen

I have tried this

   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;
        }
   } 

and change th console.writeline to

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

it worked but the other details were not displayed...

Pls help me correct this code

Upvotes: 7

Views: 18099

Answers (5)

Wezz Westbrook
Wezz Westbrook

Reputation: 35

Easiest but the messy way to do it is :

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();
}

Upvotes: -4

Sébastien Garmier
Sébastien Garmier

Reputation: 1263

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;
    }
}

I edited the answer. Now I made a class which calls an async timer to blink the text. So this will not block your programm. To show this, I made a Thread.Sleep(5000) after the text begins blinking. This could be your code which takes a while to finish. Then the text ends blinking.

Upvotes: 0

Chibueze Opata
Chibueze Opata

Reputation: 10034

I guess you're looking for this:

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);

Or to achieve WHITE TO RED blinking

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);

You can easily refactor this into a method:

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);
    }
}

Upvotes: 3

Martin Brown
Martin Brown

Reputation: 25320

Sorry to say this but flashing text is probably not a sensible thing to be doing with a console application.

The console does not support this for you so you will have to implement it yourself. As the console will only write to where the cursor is, you will have to keep moving the cursor back to the start of Alert! write out what you want and then move it back to where it was. This is not going to be pretty.

If you did want to do this the best way would be to use a timer (System.Threading.Timer). The timer would allow the rest of the application to run while between changes to the flashing text. When the timer event happened you would need to save the cursor location, move to the Alert text, Write or Blank it and then set the cursor back to the saved position. While you are doing this you need to find some way to block the file write so that you don't end up with chunks of file written where "Alert! Alert! Alert!" should be.

Finally it should be noted that this technique is going to be very strange to anyone that decides to Pipe the output of your application to a file like this: C:>MyApplication.exe > output.txt

Something like this ought to do it:

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;
     }
  }
}

Upvotes: 2

Santosh Panda
Santosh Panda

Reputation: 7341

Root cause:

  • Actually you are handling everything in a single Thread.
  • The Thread gets blocked by the infinite loop i.e. while(true) {... } inside WriteBlinkingText() method.

Solution:

Create a separate Thread for handling the blinking text. While your Main Thread would continue with the rest of code execution.

Upvotes: 3

Related Questions