2012-05-29 5 views
18

Tôi muốn đạt được một cái gì đó như thế này:Cách sửa đổi dòng văn bản giao diện điều khiển trước đó?

Time consuming operation...OK 
Another time consuming operation... 
And another one, but it completed, so...OK 

tôi hiển thị 3 dòng văn bản, mỗi người liên quan với một sợi mà có thể kết thúc sớm hay muộn. Nhưng nếu điều thứ hai hoàn thành chậm nhất là thứ ba một, tôi sẽ nhận được một cái gì đó như thế này:

Time consuming operation...OK 
Another time consuming operation... 
And another one, but it completed, so...OKOK 

Đó là tất nhiên không thể chấp nhận. Tôi biết làm thế nào để trở lại trong dòng hiện tại, nhưng có cách nào để đi UP? Tôi thề rằng tôi đã nhìn thấy nó ở đâu đó, mặc dù nó có thể là một giao diện điều khiển Linux :)

Hãy quên nó đi. Xem Far File Manager! Nó hoạt động trong giao diện điều khiển Windows, nó hoạt động ngay cả trong PowerShell! Làm thế nào để làm một cái gì đó như thế này? Và phần thú vị nhất là khôi phục trạng thái bảng điều khiển sau khi thoát. Vì vậy, có lẽ tôi nên hỏi - làm thế nào để truy cập bộ đệm giao diện điều khiển trực tiếp? Tôi cho rằng tôi sẽ cần một số mã nguồn gốc để làm thủ thuật, nhưng có thể có một cách khác? Tôi nghĩ về thanh toán bù trừ giao diện điều khiển với mỗi bản cập nhật, nhưng điều này có vẻ như quá mức cần thiết. Hoặc có lẽ nó không phải là? Nó sẽ nhấp nháy?

+0

có đã tốt đẹp nếu bạn đã bao gồm làm thế nào để "đi ngược dòng hiện tại", và không chỉ rõ rằng bạn biết điều đó. Đây là cách tôi đã làm nó: 'Console.SetCursorPosition (0, Console.CursorTop);' Tôi biết nó không trực tiếp là một phần của câu hỏi, nhưng nó liên quan, và đây là câu hỏi tôi tìm thấy khi tôi tìm kiếm nó. –

Trả lời

48

Bạn có thể di chuyển con trỏ đến bất cứ nơi nào bạn muốn: Console.SetCursorPosition hoặc sử dụng Console.CursorTop.

Console.SetCursorPosition(0, Console.CursorTop -1); 
Console.WriteLine("Over previous line!!!"); 
+1

Đúng. Đây chính là nó. Bây giờ tôi đang làm một lớp để thêm các vùng chứa như DIV trong HTML để điều khiển văn bản. Nó sẽ nhớ vị trí của mỗi container để nó có thể được thay đổi sau đó. Bây giờ tôi cuối cùng có thể hoàn thành máy chủ của tôi :) Vâng, nó vẫn là một chèn để thực hiện, nhưng có Console.MoveBufferArea sẽ trở thành tiện dụng. Cảm ơn. – Harry

4

Sử dụng trở lại vận chuyển. Mẫu này in một dòng, ghi đè lên những gì đã có trước đó.

Console.WriteLine(); 
    for (int i = 0; i <= 100; i++) 
    { 
    System.Threading.Thread.Sleep(10); 
    Console.Write("\x000DProgress: " + i); 
    } 

này hoạt động càng lâu càng tất cả các chuỗi của bạn là dưới 80 cột (hoặc bất kỳ bộ đệm thiết bị đầu cuối của bạn được đặt).

+1

Tôi cho rằng điều này chỉ hoạt động trên Windows, nhưng chưa thử nó trên mono. –

+1

Nó hoạt động tốt đẹp, nhưng không thể được sử dụng để sửa đổi đường lên. Tuy nhiên đó là một cách đơn giản để tạo một thanh tiến trình đơn hoặc cập nhật phần trăm. – Harry

+1

'\ r' cũng hoạt động thay vì' \ x000D'. – jnm2

1

Lưu ý: câu trả lời sau đây ban đầu được chỉnh sửa thành câu hỏi của OP.


Đây là giải pháp hoàn chỉnh với bản demo:

using System; 
using System.Collections.Generic; 
using System.Threading; 

namespace PowerConsole { 

    internal class Containers { 

     internal struct Container { 
      public int Id; 
      public int X; 
      public int Y; 
      public string Content; 
     } 

     public static List<Container> Items = new List<Container>(); 

     private static int Identity = 0; 

     public static int Add(string text) { 
      var c = new Container(); 
      c.Id = Identity++; 
      c.X = Console.CursorLeft; 
      c.Y = Console.CursorTop; 
      c.Content = text; 
      Console.Write(text); 
      Items.Add(c); 
      return c.Id; 
     } 

     public static void Remove(int id) { 
      Items.RemoveAt(id); 
     } 

     public static void Replace(int id, string text) { 
      int x = Console.CursorLeft, y = Console.CursorTop; 
      Container c = Items[id]; 
      Console.MoveBufferArea(
       c.X + c.Content.Length, c.Y, 
       Console.BufferWidth - c.X - text.Length, 1, 
       c.X + text.Length, c.Y 
      ); 
      Console.CursorLeft = c.X; 
      Console.CursorTop = c.Y; 
      Console.Write(text); 
      c.Content = text; 
      Console.CursorLeft = x; 
      Console.CursorTop = y; 
     } 

     public static void Clear() { 
      Items.Clear(); 
      Identity = 0; 
     } 
    } 

    internal class Program { 
     private static List<Thread> Threads = new List<Thread>(); 

     private static void Main(string[] args) { 
      Console.WriteLine("So we have some threads:\r\n"); 
      int i, id; 
      Random r = new Random(); 
      for (i = 0; i < 10; i++) { 
       Console.Write("Starting thread " + i + "...["); 
       id = Containers.Add("?"); 
       Console.WriteLine("]"); 
       Thread t = new Thread((object data) => { 
        Thread.Sleep(r.Next(5000) + 100); 
        Console.ForegroundColor = ConsoleColor.Green; 
        Containers.Replace((int)data, "DONE"); 
        Console.ResetColor(); 
       }); 
       Threads.Add(t); 
      } 
      Console.WriteLine("\n\"But will it blend?\"..."); 
      Console.ReadKey(true); 
      i = 0; 
      Threads.ForEach(t => t.Start(i++)); 
      Threads.ForEach(t => t.Join()); 
      Console.WriteLine("\r\nVoila."); 
      Console.ReadKey(true); 
     } 
    } 
} 
+1

Làm việc lekker, bạn chỉ cần thêm một dòng nữa vào cuối trong phương thức 'Replace'' Items [id] = c; '. Điều này sẽ giải quyết vấn đề thay thế liên tục nơi các ký tự bắt đầu cuộn với các giá trị sai. – Pierre

+1

@Pierre Cảm ơn bạn đã bình luận! Tôi đã không xác minh mã cho tính chính xác, vì vậy có thể có một số vấn đề với nó. – Stijn