C# 正在将Console.WriteLine()重定向到Textbox
我正在Visual Studio 2010中使用C#构建此应用程序 基本上有两个文件,form1.cs(windows窗体)和program.cs(所有逻辑所在) 有一个运行按钮和一个空白文本框 当用户点击运行按钮时,program.cs将执行一些任务,并使用控制台上的C# 正在将Console.WriteLine()重定向到Textbox,c#,redirect,user-interface,console.writeline,C#,Redirect,User Interface,Console.writeline,我正在Visual Studio 2010中使用C#构建此应用程序 基本上有两个文件,form1.cs(windows窗体)和program.cs(所有逻辑所在) 有一个运行按钮和一个空白文本框 当用户点击运行按钮时,program.cs将执行一些任务,并使用控制台上的Console.WriteLine()不断打印进度(命令提示符) 问题:如何打印到form1上的文本框而不是打印到命令提示符? 我需要在没有任何用户操作的情况下不断打印进度 提前谢谢 顺便说一下,它不一定是一个文本框,它可以是一个
Console.WriteLine()
不断打印进度(命令提示符)
问题:如何打印到form1上的文本框而不是打印到命令提示符?
我需要在没有任何用户操作的情况下不断打印进度
提前谢谢
顺便说一下,它不一定是一个文本框,它可以是一个标签或其他可以接收文本的东西。我选择textbox是因为它对我来说更有意义。不知道它是否能工作,但您可以尝试重定向控制台输出 使用
Console.SetOut()
并创建TextWriter
的派生,它覆盖WriteLine()
方法,只需将方法参数分配给TextBox.Text
应该有效。将
文本框
放在表单(多行
已启用)或文本区域上,然后您可以在循环中执行操作
txtOutput.Text += "Progress " + percent + "% completed." + Environment.NewLine();
首先,创建一个新的
文本编写器,它可以写入文本框。它只需要重写接受字符的Write
方法,但这将是非常低效的,因此最好至少用字符串重写方法
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; }
}
}
在本例中,我让它只接受一个控件
,它可以是一个文本框
、一个标签
,或者其他任何东西。如果您想将其更改为一个标签
,则可以
然后,只需将控制台输出设置为此编写器的新实例,指向某个文本框或标签:
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; }
}
}
我用这样的东西作为列表框:
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
控制台放线(_-writer) 问题是,循环在program.cs中,它无法识别文本框,文本框只存在于form1.cs中,所以不要使用控制台应用程序…只需使用一个简单的GUI应用程序即可。我是否将“console.SetOut(new TextboxWriter(textbox1));”放在带有program.cs的Main()中?program.cs无法识别form1.cs中的textbox1,并且该textbox1在程序中不存在。cs@sora0419不,您应该将其放在表单的定义中。当我创建ControlWriter时,我得到一个错误,它说“'ControlWriter'没有实现继承的抽象成员'System.IO.TextWriter.Encoding.get'”我遗漏了什么?@sora0419刚刚为编码添加了一个实现。我尝试了第一种方法。程序停止打印到控制台,但是文本框中也没有打印任何内容。我将ControlWriter类放在命名空间Form1内,但放在公共部分类Form1外:Form{}。在初始化Component()之后,我将“Console.SetOut(新的ControlWriter(textbox1));”放在Form1类中;我是不是误解了什么,把函数放错地方了?虽然你原来的问题似乎已经得到了回答,但如果你正在向文本框发送大量更新,要当心,因为你可能会淹没消息队列,导致表单变得毫无响应。形态反应也取决于“某些计算”的强度。您可能需要考虑后台进程线程,它将进度报告回窗体。@ Rikdavin注意到,这样的选择将需要有能力将所有控制台写入更改为其他内容。如果他无法控制该代码(即,它是库代码),那么这可能不是一个选项,也可能只是不实用。
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