2009-12-17 32 views
31

Tôi chỉ muốn biết cách tạo các hoạt ảnh đơn giản như nhấp nháy, di chuyển các nội dung trên các ứng dụng giao diện điều khiển C#. Có phương pháp đặc biệt nào cho việc này không?Hình ảnh động của giao diện điều khiển

+0

+1 Yêu câu hỏi này, IMMD =) –

Trả lời

3

Bạn sẽ cần phải sử dụng Console.ForegroundColor, Console.BackgroundColorConsole.SetCursorPosition(int, int)

EDIT: Đối với nguồn cảm hứng, Let's Dance

+1

Tôi rất thích xem khung hình hoạt ảnh của Lets Dance dưới dạng văn bản, vì vậy chúng tôi có thể triển khai hoạt ảnh như một Bảng điều khiển Spinner. – TaterJuice

0

tôi không quá chắc chắn tôi biết chính xác những gì bạn đang ở trên về. nhưng tôi sẽ cho nó một shot. Tôi nghĩ rằng cách lớn nhất và tốt nhất để gây ra "nhấp nháy" ảnh hưởng (hoặc những gì tôi nghĩ rằng ảnh hưởng nhấp nháy là) là sử dụng một vận chuyển trở lại. Cách tốt nhất để giải thích cho bạn là cho bạn thấy thử nghiệm Foo Bar. bắt đầu một dự án mới và trong chức năng chính của bạn, hãy thử điều này.

Console.WriteLine("Foo/nBar"); 

Đầu ra sẽ trông như thế này

Foo 
Bar 

Nhưng nếu bạn sử dụng một trở về vận chuyển.

Console.WriteLine("Foo/rBar"); 

Kết quả sẽ trông giống như

Bar 

lý do này

ở đây là Foo được viết, sau đó trở về vận chuyển đưa bạn trở lại khi bắt đầu dòng, sau đó Bar được viết. Tất cả những gì bạn từng thấy là Bar. Điều này có thể hữu ích cho việc "di chuyển" mọi thứ trên một dòng, thay vì viết lại những thứ giống nhau trên nhiều dòng. Một cách để tiến triển sẽ là sử dụng Console.Write(); Hãy thử điều này.

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

Sản lượng nên

Loading 

Tiếp theo là một Fullstop mỗi giây trong 10 giây.

Nếu bạn kết hợp vận chuyển trở lại bằng bàn điều khiển.Write(); chức năng bạn có thể viết nhiều thứ trên một dòng, xóa dòng và viết một cái gì đó khác, hoặc thực sự, điều tương tự chỉ chuyển động nhẹ. (Điều này tất nhiên sẽ cần nhiều hơn tôi đã chỉ cho bạn, như ghi âm nơi "đối tượng" bạn đang kiểm soát nằm. Nếu bạn muốn một ví dụ ngắn tôi sẽ được hạnh phúc để làm một, chỉ cần bình luận và yêu cầu tôi cho nó :)

Chỉnh sửa: Tôi nhận thấy mọi người đề cập đến màu sắc, mà tôi đã quên. Nếu bạn đang làm phim hoạt hình tôi đoán màu sắc sẽ là một phải. ForegroundColor và BackgroundColor là vị trí của nó. lưu ý rằng ForegroundColor sẽ áp dụng cho các ký tự tiếp theo được ghi vào bàn điều khiển, nó sẽ không hoàn toàn tái chế giao diện điều khiển. /Sửa

Tôi hy vọng điều này sẽ giúp,

Skintkingle;)

+0

Điều này không, thật không may, làm việc cho hầu hết các trường hợp. Bạn không thể đi lên một dòng với \ r, vì vậy bạn đang rất hạn chế mà không cần sử dụng Console.SetCursorPosition –

+0

Ah có tất nhiên. Tôi không chơi xung quanh trong Console nhiều nữa, tôi quên những điều rõ ràng nhất. :) – Skintkingle

41

truyền thống điều khiển Spinner:

static void Main(string[] args) 
    { 
     ConsoleSpiner spin = new ConsoleSpiner(); 
     Console.Write("Working...."); 
     while (true) 
     { 
      spin.Turn(); 
     } 
    } 

public class ConsoleSpiner 
{ 
    int counter; 
    public ConsoleSpiner() 
    { 
     counter = 0; 
    } 
    public void Turn() 
    { 
     counter++;   
     switch (counter % 4) 
     { 
      case 0: Console.Write("/"); break; 
      case 1: Console.Write("-"); break; 
      case 2: Console.Write("\\"); break; 
      case 3: Console.Write("|"); break; 
     } 
     Console.SetCursorPosition(Console.CursorLeft - 1, Console.CursorTop); 
    } 
} 
4

Chỉ cần thấy điều này và một vài chủ đề khác về nó và yêu loại công cụ này ! Tôi lấy đoạn mã tốt đẹp của Tuukka và cải thiện nó một chút để lớp có thể dễ dàng được thiết lập chỉ là về bất kỳ trình tự quay nào. Tôi có lẽ sẽ thêm một số accessors và một constructor quá tải để đánh bóng nó ra và đặt nó trong hộp công cụ của ol. Nội dung thú vị!

class ConsoleSpinner 
{ 
    int counter; 
    string[] sequence; 

    public ConsoleSpinner() 
    { 
     counter = 0; 
     sequence = new string[] { "/", "-", "\\", "|" }; 
     sequence = new string[] { ".", "o", "0", "o"}; 
     sequence = new string[] { "+", "x" }; 
     sequence = new string[] { "V", "<", "^", ">" }; 
     sequence = new string[] { ". ", ".. ", "... ", "...." }; 
    } 

    public void Turn() 
    { 
     counter++; 

     if (counter >= sequence.Length) 
      counter = 0; 

     Console.Write(sequence[counter]); 
     Console.SetCursorPosition(Console.CursorLeft - sequence[counter].Length, Console.CursorTop); 
    } 
} 
1

Tôi nghĩ tôi sẽ kêu gọi bằng phiên bản mã được liệt kê trước đây của tôi. Ở đây là:

class ConsoleSpinner 
{ 
    bool increment = true, 
     loop = false; 
    int counter = 0; 
    int delay; 
    string[] sequence; 

    public ConsoleSpinner(string sSequence = "dots", int iDelay = 100, bool bLoop = false) 
    { 
     delay = iDelay; 
     if (sSequence == "dots") 
     { 
      sequence = new string[] { ". ", ".. ", "... ", "...." }; 
      loop = true; 
     } 
     else if (sSequence == "slashes") 
      sequence = new string[] { "/", "-", "\\", "|" }; 
     else if (sSequence == "circles") 
      sequence = new string[] { ".", "o", "0", "o" }; 
     else if (sSequence == "crosses") 
      sequence = new string[] { "+", "x" }; 
     else if (sSequence == "arrows") 
      sequence = new string[] { "V", "<", "^", ">" }; 
    } 

    public void Turn() 
    { 
     if (loop) 
     { 
      if (counter >= sequence.Length - 1) 
       increment = false; 
      if (counter <= 0) 
       increment = true; 

      if (increment) 
       counter++; 
      else if (!increment) 
       counter--; 
     } 
     else 
     { 
      counter++; 

      if (counter >= sequence.Length) 
       counter = 0; 
     } 

     Console.Write(sequence[counter]); 
     Console.SetCursorPosition(Console.CursorLeft - sequence[counter].Length, Console.CursorTop); 

     System.Threading.Thread.Sleep(delay); 
    } 
} 

Thêm chậm trễ (không may qua Thread.Sleep() nhưng, hey), khả năng để lặp các chuyển tiếp hình ảnh động và ngược (bắt đầu đảo ngược khi nó chạm cuối cùng), và cải tiến chung chung. Thưởng thức!

1

Đây sẽ là phương pháp ưa thích của tôi:

public sealed class Spinner 
{ 
    private static Lazy<Spinner> lazy = 
     new Lazy<Spinner>(()=> new Spinner()); 

    public static void Reset() 
    { 
     lazy = new Lazy<Spinner>(()=> new Spinner()); 
    } 

    public static Spinner Instance { get { return lazy.Value; }} 

    private readonly int _consoleX; 
    private readonly int _consoleY; 
    private readonly char[] _frames = { '|', '/', '-', '\\' }; 
    private int _current; 

    private Spinner() 
    { 
     _current = 0; 
     _consoleX = Console.CursorLeft; 
     _consoleY = Console.CursorTop; 
    } 

    public void Update() 
    { 
     Console.Write(_frames[_current]); 
     Console.SetCursorPosition(_consoleX, _consoleY); 

     if (++_current >= _frames.Length) 
      _current = 0; 
    } 
} 

Gọi Spinner.Instance.Update() để bắt đầu spinner ở vị trí hiện tại của giao diện điều khiển. Bất kỳ cuộc gọi liên tiếp nào cũng sẽ hiển thị khung tiếp theo ở cùng một vị trí.

Gọi Spinner.Reset() nếu bạn muốn viết thêm văn bản và sau đó thêm một spinner mới tại một vị trí mới.

8

Đây là máy quay của tôi. Mục đích của nó là để có một chương trình làm một số công việc trong khi các màn hình spinner để cho người dùng biết một cái gì đó thực sự xảy ra:

public class Spinner : IDisposable 
    { 
    private const string Sequence = @"/-\|"; 
    private int counter = 0; 
    private readonly int left; 
    private readonly int top; 
    private readonly int delay; 
    private bool active; 
    private readonly Thread thread; 

    public Spinner(int left, int top, int delay = 100) 
    { 
     this.left = left; 
     this.top = top; 
     this.delay = delay; 
     thread = new Thread(Spin); 
    } 

    public void Start() 
    { 
     active = true; 
     if (!thread.IsAlive) 
      thread.Start(); 
    } 

    public void Stop() 
    { 
     active = false; 
     Draw(' '); 
    } 

    private void Spin() 
    { 
     while (active) 
     { 
      Turn(); 
      Thread.Sleep(delay); 
     } 
    } 

    private void Draw(char c) 
    { 
     Console.SetCursorPosition(left, top); 
     Console.ForegroundColor = ConsoleColor.Green; 
     Console.Write(c); 
    } 

    private void Turn() 
    { 
     Draw(Sequence[++counter % Sequence.Length]); 
    } 

    public void Dispose() 
    { 
     Stop(); 
    } 
    } 

Và bạn sử dụng lớp như thế này:

 var spinner = new Spinner(10, 10); 

    spinner.Start(); 

    // Do your work here instead of sleeping... 
    Thread.Sleep(10000); 

    spinner.Stop(); 
+0

Ví dụ tuyệt vời, chính xác những gì tôi muốn: Trong khi tôi đang làm một công việc chuyên sâu tôi muốn một số tiến bộ – jjay225

+0

Xin hãy xem anwser của tôi, tôi lấy mã của bạn và sửa đổi nó một chút. – Rumplin

1

vĩ đại làm việc với ConsoleSpinner và triển khai chuỗi. Cảm ơn mã. Tôi nghĩ về việc chia sẻ cách tiếp cận tùy chỉnh của mình.

public class ConsoleSpinner 
{ 
    static string[,] sequence = null; 

    public int Delay { get; set; } = 200; 

    int totalSequences = 0; 
    int counter; 

    public ConsoleSpinner() 
    { 
     counter = 0; 
     sequence = new string[,] { 
      { "/", "-", "\\", "|" }, 
      { ".", "o", "0", "o" }, 
      { "+", "x","+","x" }, 
      { "V", "<", "^", ">" }, 
      { ". ", ".. ", "... ", "...." }, 
      { "=> ", "==> ", "===> ", "====>" }, 
      // ADD YOUR OWN CREATIVE SEQUENCE HERE IF YOU LIKE 
     }; 

     totalSequences = sequence.GetLength(0); 
    } 

    /// <summary> 
    /// 
    /// </summary> 
    /// <param name="sequenceCode"> 0 | 1 | 2 |3 | 4 | 5 </param> 
    public void Turn(string displayMsg = "", int sequenceCode = 0) 
    { 
     counter++; 

     Thread.Sleep(Delay); 

     sequenceCode = sequenceCode > totalSequences - 1 ? 0 : sequenceCode; 

     int counterValue = counter % 4; 

     string fullMessage = displayMsg + sequence[sequenceCode, counterValue]; 
     int msglength = fullMessage.Length; 

     Console.Write(fullMessage); 

     Console.SetCursorPosition(Console.CursorLeft - msglength, Console.CursorTop); 
    } 
} 

Thực hiện:

ConsoleSpinner spinner = new ConsoleSpinner(); 
spinner.Delay = 300; 
while (true) 
{ 
    spinner.Turn(displayMsg: "Loading ",sequenceCode:5); 
} 

Output:

enter image description here

0

Tôi đã anwser từ @ThisGuy và sửa đổi nó một chút, nhưng tôi nhận thấy, rằng đôi khi hàng không được xóa như nó cần.

static void Main(string[] args) 
    { 
     Console.WriteLine("1"); 
     var tddf = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd 4343",() => 
     { 
      return ""; 
     }); 
     Console.WriteLine("2"); 
     var tdd = XConsole.BusyIndicator("test 0 trtg fdfdfvdgd",() => 
     { 
      Thread.Sleep(1); 
      return ""; 
     }); 
     Console.WriteLine("3"); 
     var t = XConsole.BusyIndicator("test 1 trtg vdgd",() => 
     { 
      Thread.Sleep(1000); 
      return ""; 
     }); 
     Console.WriteLine("4"); 
     var xt = XConsole.BusyIndicator("test 2",() => 
     { 
      Thread.Sleep(2000); 
      return ""; 
     }); 
     var xtx = XConsole.BusyIndicator("test 2 csds fsd fdsf ds s",() => 
     { 
      Thread.Sleep(2000); 
      return ""; 
     }); 

     Console.WriteLine("5"); 
     Thread.Sleep(4000); 
    } 

Spinner lớp:

public class Spinner : IDisposable 
    { 
     private const string Sequence1 = @"/-\|"; 
     private const string Sequence3 = @".o0o"; 
     private const string Sequence2 = @"<^>v"; 
     private const string Sequence4 = @"#■."; 
     private const string Sequence5 = @"▄▀"; 
     private const string Sequence = @"└┘┐┌"; 
     private string BusyMessage = ""; 
     private int counter = 0; 
     private readonly int delay; 
     private bool active; 
     private readonly Thread thread; 

     public Spinner(int delay = 200) 
     { 
      this.delay = delay; 
      thread = new Thread(Spin); 
     } 

     public void Start() 
     { 
      active = true; 
      Console.CursorVisible = false; 
      if (!thread.IsAlive) 
      { 
       thread.Start(); 
      } 
     } 

     public void Start(string busyMessage) 
     { 
      BusyMessage = busyMessage; 
      Start(); 
     } 

     public void Stop() 
     {   
      active = false; 
      Console.CursorVisible = true; 
      ClearCurrentConsoleLine(); 
      BusyMessage = ""; 
     } 

private static void ClearCurrentConsoleLine() 
{ 
    int currentLineCursor = Console.CursorTop; 
    Console.SetCursorPosition(0, Console.CursorTop); 
    Console.Write(new string(' ', Console.WindowWidth)); 
    Console.SetCursorPosition(0, currentLineCursor); 
} 

     private void Spin() 
     { 
      while (active) 
      { 
       Turn(); 
       Thread.Sleep(delay); 
      } 
     } 

     /// <summary> 
     /// Draws the busy indicator 
     /// </summary> 
     /// <param name="c">if empty char, then clear screen</param> 
    private void Draw(char c) 
    { 
     int left = Console.CursorLeft; 
     int top = Console.CursorTop; 

     Console.Write('['); 
     Console.ForegroundColor = ConsoleColor.Green; 
     Console.Write(c); 
     Console.ForegroundColor = ConsoleColor.Gray; 
     Console.Write(']'); 
     if (!string.IsNullOrEmpty(BusyMessage)) 
     { 
      Console.Write(" " + BusyMessage); 
     } 

     //reset cursor position 
     Console.SetCursorPosition(left, top); 
    } 

     private void Turn() 
     { 
      Draw(Sequence[++counter % Sequence.Length]); 
     } 

     public void Dispose() 
     { 
      Stop(); 
     } 
    } 

My console lớp:

public static class XConsole { 
    public static T BusyIndicator<T>(Func<T> action) 
    { 
     T result; 

     using (var spinner = new Spinner()) 
     { 
      spinner.Start(); 

      result = action(); 

      spinner.Stop(); 
     } 

     return result; 
    } 

    public static T BusyIndicator<T>(string content, Func<T> action) 
    { 
     T result; 

     using (var spinner = new Spinner()) 
     { 
      spinner.Start(content); 

      result = action(); 

      spinner.Stop(); 
     } 

     return result; 
    } 
} 

Tại sao tôi thấy kết quả này đôi khi?

1 
2 
3 st 0 trtg fdfdfvdgd ] 
4 
[└] test 2 csds fsd fdsf ds s 

Có vẻ như Dispose không kích hoạt? Hoặc bắt đầu một số mới Task alredy?

Nó sẽ giống như thế này:

1 
2 
3 
4 
[└] test 2 csds fsd fdsf ds s 

UPDATE:

tôi thêm ClearCurrentConsoleLine(); và thay đổi phương pháp Draw, điều này cố định vấn đề này.

+0

Tôi sẽ giả sử nó không phải là chủ đề an toàn, nhưng làm thế nào để sửa lỗi này? – Rumplin

+0

Hai giấc ngủ đầu tiên nhỏ hơn độ trễ ban đầu để vẽ (200 ms). Đó là lý do tại sao dòng thứ 3 là dòng đầu tiên hiển thị thông báo. Giấc ngủ của bạn đang xảy ra trong cuộc gọi lại, vì vậy tất cả chúng đều được khởi động song song. Bạn đang in trạng thái tại vị trí giao diện điều khiển hiện tại thay đổi trong quá trình thực thi. Hardcode left = 0 và top = 5 và bạn sẽ thấy kết quả mong muốn. Với nói, tôi không hoàn toàn hiểu những gì bạn đang cố gắng làm. – ThisGuy

+0

Đọc tệp từ chia sẻ mạng. Với điều này người dùng sẽ thấy rằng một cái gì đó đang xảy ra. Nó đọc một lượng lớn tập tin và mất một thời gian với chia sẻ mạng. 'Thread.Sleep' ở đây mô phỏng điều đó. – Rumplin

Các vấn đề liên quan