33

我正在使用 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.");
        }
    }
}

有一个运行按钮和一个空白文本框

当用户点击“运行”按钮时,program.cs 将执行一些任务并不断在控制台上打印出进度Console.WriteLine()(命令提示符)。

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

提前致谢!

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

4

4 回答 4

68

首先创建一个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; }
    }
}

在这种情况下,我让它只接受 a Control,它可以是 a Textbox、 aLabel或其他。如果你想把它改成一个Label就好了。

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

Console.SetOut(new ControlWriter(textbox1));

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

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));
于 2013-09-10T19:16:00.257 回答
1

不知道它是否会起作用,但您可以尝试重定向控制台输出。

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

于 2013-09-10T19:09:26.650 回答
1

我将这样的东西用于列表框:

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

于 2014-06-20T12:22:04.707 回答
-2

放在textbox表单(multiple lines启用)或文本区域,然后你可以在你的循环中做

txtOutput.Text += "Progress " + percent + "% completed." + Environment.NewLine();
于 2013-09-10T19:09:35.380 回答