将Console.WriteLine()重定向到文本框
我正在使用C#在Visual Studio 2010中构建此应用程序。
基本上有2个文件,form1.cs(这是windows窗体)和program.cs(所有逻辑都在这里)。
//form1.cs public partial class Form1 : Form { //runButton_click function } //program.cs class Program { static void Main() { while(blah-condition) { //some calculation Console.WriteLine("Progress " + percent + "% completed."); } } }
有一个运行按钮和一个空白文本框 。
当用户点击Run 按钮时 ,program.cs将执行一些任务并使用Console.WriteLine()
不断地将进度打印到控制台(命令提示符)。
问题:如何打印到form1上的文本框而不是打印到命令提示符? 我需要在没有任何用户操作的情况下持续打印进度。
提前致谢!
顺便说一句,它不必是文本框,它可以是标签或其他可以采用文本的东西。 我选择了文本框,因为它对我来说更有意义。
首先创建一个能够写入文本框的新TextWriter
。 它只需要覆盖接受char
的Write
方法,但这样效率很低,所以最好用字符串覆盖至少方法。
public class ControlWriter : TextWriter { private Control textbox; public ControlWriter(Control textbox) { this.textbox = textbox; } public override void Write(char value) { textbox.Text += value; } public override void Write(string value) { textbox.Text += value; } public override Encoding Encoding { get { return Encoding.ASCII; } } }
在这种情况下,我已经接受了一个Control
,它可以是一个Textbox
,一个Label
或者其他什么。 如果你想将它改为只是一个没问题的Label
。
然后只需将控制台输出设置为此writer的新实例,指向一些文本框或标签:
Console.SetOut(new ControlWriter(textbox1));
如果您希望将输出写入控制台以及文本框,我们可以使用此类创建将写入多个编写器的编写器:
public class MultiTextWriter : TextWriter { private IEnumerable writers; public MultiTextWriter(IEnumerable writers) { this.writers = writers.ToList(); } public MultiTextWriter(params TextWriter[] writers) { this.writers = writers; } public override void Write(char value) { foreach (var writer in writers) writer.Write(value); } public override void Write(string value) { foreach (var writer in writers) writer.Write(value); } public override void Flush() { foreach (var writer in writers) writer.Flush(); } public override void Close() { foreach (var writer in writers) writer.Close(); } public override Encoding Encoding { get { return Encoding.ASCII; } } }
然后使用这个我们可以做:
Console.SetOut(new MultiTextWriter(new ControlWriter(textbox1), Console.Out));
我使用这样的列表框:
public class ListBoxWriter : TextWriter //this class redirects console.writeline to debug listbox { private readonly ListBox _list; private StringBuilder _content = new StringBuilder(); public ListBoxWriter(ListBox list) { _list = list; } public override Encoding Encoding { get { return Encoding.UTF8; } } public override void Write(char value) { base.Write(value); _content.Append(value); if (value != '\n') return; if (_list.InvokeRequired) { try { _list.Invoke(new MethodInvoker(() => _list.Items.Add(_content.ToString()))); _list.Invoke(new MethodInvoker(() => _list.SelectedIndex = _list.Items.Count - 1)); _list.Invoke(new MethodInvoker(() => _list.SelectedIndex = -1)); } catch (ObjectDisposedException ex) { Console.WriteLine(Resources.Exception_raised + " (" + ex.Message + "): " + ex); } } else { _list.Items.Add(_content.ToString()); _list.SelectedIndex = _list.Items.Count - 1; _list.SelectedIndex = -1; } _content = new StringBuilder(); } }
在我的主要申请中:
_writer = new ListBoxWriter(DebugWin); // DebugWin is the name og my listbox
Console.SetOut(_writer);
不知道它是否可行,但您可以尝试重定向控制台输出。
使用Console.SetOut()
并创建TextWriter
派生,它会覆盖WriteLine()
方法并简单地将方法参数赋值给TextBox.Text
应该可以工作。
将textbox
放在窗体上(启用multiple lines
)或文本区域,然后您可以在循环中执行
txtOutput.Text += "Progress " + percent + "% completed." + Environment.NewLine();