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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-10 13:01:38  来源:igfitidea点击:

Redirecting Console.WriteLine() to Textbox

c#redirectuser-interfaceconsole.writeline

提问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 TextWriterthat is capable of writing to a textbox. It only needsto override the Writemethod 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 Labelthat 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 TextWriterwhich overrides WriteLine()method and simply assign method parameter to your TextBox.TextShould work.

使用Console.SetOut()并创建TextWriter其覆盖WriteLine()方法的衍生物,并简单地将方法参数分配给您的“TextBox.Text应该”工作。

回答by Dan Hunex

put textboxon the form ( multiple linesenabled) 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);