我正在使用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上打印文本框而不是打印到命令提示符? 我需要在没有任何用户操作的情况下持续打印进度。
提前致谢!
顺便说一句,它不必是文本框,它可以是标签或其他可以带文本的东西。我选择了文本框,因为它对我来说更有意义。
答案 0 :(得分:46)
首先创建一个能够写入文本框的新TextWriter
。只有需要来覆盖接受Write
的{{1}}方法,但这样效率很低,所以最好用字符串覆盖至少方法。
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; }
}
}
,可以是Control
,Textbox
或其他任何内容。如果您想将其更改为Label
,那就没问题了。
然后只需将控制台输出设置为此编写器的新实例,指向某个文本框或标签:
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; }
}
}
答案 1 :(得分:2)
我使用这样的列表框:
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);
答案 2 :(得分:1)
不知道它是否可行,但您可以尝试重定向控制台输出。
使用Console.SetOut()
并创建TextWriter
的衍生版,该版本会覆盖WriteLine()
方法,只需将方法参数指定给TextBox.Text
应该工作。
答案 3 :(得分:-2)
将textbox
放在表单(multiple lines
已启用)或文本区域,然后您可以在循环中执行
txtOutput.Text += "Progress " + percent + "% completed." + Environment.NewLine();