将 Console.WriteLine() 重定向到文本框

将 Console.WriteLine() 重定向到文本框

问题描述:

我正在使用 C# 在 Visual Studio 2010 中构建此应用程序.

I'm building this application in Visual Studio 2010 using C#.

基本上有 2 个文件,form1.cs(即 windows 窗体)和 program.cs(所有逻辑所在).

Basically there are 2 files, form1.cs (which is the windows form) and program.cs (where all the logic lies).

//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 button and a blank textbox.

当用户点击 Run button 时,program.cs 将执行一些任务并使用 Console.WriteLine() 不断地将进度打印到控制台上(命令提示符).

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

问题:如何打印到 form1 上的文本框而不是打印到命令提示符?我需要在没有任何用户操作的情况下不断打印进度.

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.

提前致谢!

顺便说一句,它不一定是一个文本框,它可以是一个标签或其他可以接受文本的东西.我选择文本框是因为它对我来说更有意义.

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.

首先创建一个能够写入文本框的新 TextWriter.它只需要覆盖接受 charWrite 方法,但这会非常低效,所以最好至少覆盖该方法用一个字符串.

Start by creating a new TextWriter that is capable of writing to a textbox. It only needs to 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.

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 就可以了.

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.

然后只需将控制台输出设置为此编写器的新实例,指向某个文本框或标签:

Then just set the console output to a new instance of this writer, pointing to some textbox or label:

Console.SetOut(new ControlWriter(textbox1));

如果您希望将输出写入控制台以及到文本框,我们可以使用这个类来创建一个写入多个写入器的写入器:

If you want the output to be written to the console as well as to 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; }
    }
}

然后我们可以这样做:

Console.SetOut(new MultiTextWriter(new ControlWriter(textbox1), Console.Out));