C# 将 Console.WriteLine() 重定向到文本框
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/18726852/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Redirecting Console.WriteLine() to Textbox
提问by sora0419
I'm building this application in Visual Studio 2010 using C#.
我正在使用 C# 在 Visual Studio 2010 中构建此应用程序。
Basically there are 2 files, form1.cs (which is the windows form) and program.cs (where all the logic lies).
基本上有 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.");
}
}
}
There is a Run buttonand a blank textbox.
有一个运行按钮和一个空白文本框。
When the user hits the Run button, program.cs will perform some task and constantly printing out the progress using Console.WriteLine()
onto the console (command prompt).
当用户点击运行按钮时,program.cs 将执行一些任务并不断地将进度打印Console.WriteLine()
到控制台(命令提示符)上。
Question: How can I print to the textbox on form1 instead of printing into command prompt? I will need to print the progress constantly without any user action.
问题:如何打印到 form1 上的文本框而不是打印到命令提示符?我需要在没有任何用户操作的情况下不断打印进度。
Thanks in advance!
提前致谢!
By the way, it doesn't have to be a textbox, it can be a label or something else that can take text. I chose textbox because it makes more sense to me.
顺便说一句,它不一定是一个文本框,它可以是一个标签或其他可以接受文本的东西。我选择了文本框,因为它对我来说更有意义。
采纳答案by Servy
Start by creating a new TextWriter
that is capable of writing to a textbox. It only needsto override the Write
method that accepts a char
, but that would be ungodly inefficient, so it's better to overwrite at least the method with a string.
首先创建一个TextWriter
能够写入文本框的新内容。它只需要覆盖Write
接受 a的方法char
,但这会非常低效,因此最好至少用字符串覆盖该方法。
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; }
}
}
In this case I've had it just accept a Control
, which could be a Textbox
, a Label
, or whatever. If you want to change it to just a Label
that would be fine.
在这种情况下,我让它只接受 a Control
,它可以是 a Textbox
、 aLabel
或其他任何东西。如果你想把它改成一个Label
就好了。
Then just set the console output to a new instance of this writer, pointing to some textbox or label:
然后将控制台输出设置为这个 writer 的一个新实例,指向一些文本框或标签:
Console.SetOut(new ControlWriter(textbox1));
If you want the output to be written to the console as well asto the textbox we can use this class to create a writer that will write to several writers:
如果您希望将输出写入控制台以及文本框,我们可以使用此类创建一个写入多个写入器的写入器:
public class MultiTextWriter : TextWriter
{
private IEnumerable<TextWriter> writers;
public MultiTextWriter(IEnumerable<TextWriter> 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; }
}
}
Then using this we can do:
然后使用这个我们可以做到:
Console.SetOut(new MultiTextWriter(new ControlWriter(textbox1), Console.Out));
回答by quirell
Don't know if it will work, but you could try to redirect console output.
不知道它是否会起作用,但您可以尝试重定向控制台输出。
Use Console.SetOut()
and create derivative of TextWriter
which overrides WriteLine()
method and simply assign method parameter to your TextBox.Text
Should work.
使用Console.SetOut()
并创建TextWriter
其覆盖WriteLine()
方法的衍生物,并简单地将方法参数分配给您的“TextBox.Text
应该”工作。
回答by Dan Hunex
put textbox
on the form ( multiple lines
enabled) or text area then you can do in your loop
放在textbox
表单(已multiple lines
启用)或文本区域上,然后您可以在循环中执行
txtOutput.Text += "Progress " + percent + "% completed." + Environment.NewLine();
回答by user38723
I use sth like this for a listbox:
我将这样的东西用于列表框:
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();
}
}
and in my main application:
在我的主要应用程序中:
_writer = new ListBoxWriter(DebugWin); // DebugWin is the name og my listbox
Console.SetOut(_writer);
Console.SetOut(_writer);