如何将控制台输出写入多线程 MVC 建模应用程序中的控件?
How to write console output to a control within multi threading MVC modeled application?
我找到了一种非常简单而优雅的方法来通过这个 link 将控制台输出定向到文本框,但现在我找不到在我的演示器中实现它的方法 class 所以它可以在我需要的任何地方使用。这意味着在主线程中,而且在主线程中启动的所有 classes 中。
问题是我在网上找到的 class 中有一个控件(文本框),输出指向该控件。在我的演示器 class 中,我无法定义控件。因此,当我启动演示者线程,然后启动我在其中定义 TextWriter 的表单时,表单中生成的输出将按预期写入文本框,但每当我 Console.Writeline 在演示者或其他实例中创建在演示器中,它仍然被定向到标准调试输出 window...
正如您可能已经看到的那样,我对 MVC 模型还比较陌生。 :)
所以,TextBoxStreamWriter:
public class TextBoxStreamWriter : TextWriter
{
TextBox _output ;
public TextBoxStreamWriter(TextBox output)
{
_output = output;
}
public override void Write(char value)
{
MethodInvoker action =
delegate
{
_output.AppendText(value.ToString());
};
_output.BeginInvoke(action);
}
public override Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
在我的演示者中 class:
public MTMainPresenter(IMTMainForm view)
{
_view = view;
HandleShizzle();
Console.Writeline("Presenter initialized :( "); // << Doesn't work as I want it to...
}
program.cs:
private static MTMainPresenter _presenter;
static void Main()
{
var mainForm = new MTMainForm();
_presenter = new MTMainPresenter(mainForm);
Application.Run(mainForm);
}
在我的表格中:
TextWriter _writer = null;
private void Form1_Load(object sender, EventArgs e)
{
_writer = new TextBoxStreamWriter(txtboxConsole);
Console.SetOut(_writer);
Console.Writeline("Yay !"); // << Works fine, the way I want it to
}
所以基本上,我以生成 Console.WriteLine() 的形式创建了一个测试按钮,这工作得很好。但是当我在演示器中执行相同操作时,它会写入标准调试 window。我已经尝试在 Procgram.cs class 中初始化 TextWriter,但由于它有一个 TextBox 控件,需要分配它,我对如何解决这个问题有点迷茫...
我很确定这很容易修复,但我缺乏经验。
提前致谢
P
我明白了。经过一段时间的思考并尝试了一些事情之后,我找到了一种方法来做到这一点。可能会有更好的方法,所以如果这不符合最佳实践,请纠正我。 :) 但它有效...
我现在可以在任何地方调用 Console.WriteLine()(MTMainForm、Presenter、我的 Presenter 中自定义对象的任何实例...)。
我正在做的步骤...
1. 创建表格
2. 在窗体中,创建链接到控件的编写器
3. 返回 Program.cs,从表单中获取创建的编写器
4.将输出偏离到作者
5. 运行 表格...
Program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var mainForm = new MTMainForm();
TextWriter wrt = mainForm.GetWriter();
Console.SetOut(wrt);
_presenter = new MTMainPresenter(mainForm);
Application.Run(mainForm);
}
MTMainForm:
TextBoxStreamWriter _writer = null;
public MTMainForm()
{
InitializeComponent();
_writer = new TextBoxStreamWriter(textBoxConsole);
}
public TextBoxStreamWriter GetWriter()
{
return _writer;
}
TextBoxStreamWriter:
public class TextBoxStreamWriter : TextWriter
{
TextBox _output;
public TextBoxStreamWriter(TextBox output)
{
_output = output;
}
public override void Write(char value)
{
MethodInvoker action =
delegate
{
_output.AppendText(value.ToString());
if (_output.Text.Length > 4000)
_output.Text = _output.Text.Substring(2000, _output.Text.Length - 2000);
};
_output.BeginInvoke(action);
}
public override Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
我找到了一种非常简单而优雅的方法来通过这个 link 将控制台输出定向到文本框,但现在我找不到在我的演示器中实现它的方法 class 所以它可以在我需要的任何地方使用。这意味着在主线程中,而且在主线程中启动的所有 classes 中。
问题是我在网上找到的 class 中有一个控件(文本框),输出指向该控件。在我的演示器 class 中,我无法定义控件。因此,当我启动演示者线程,然后启动我在其中定义 TextWriter 的表单时,表单中生成的输出将按预期写入文本框,但每当我 Console.Writeline 在演示者或其他实例中创建在演示器中,它仍然被定向到标准调试输出 window...
正如您可能已经看到的那样,我对 MVC 模型还比较陌生。 :)
所以,TextBoxStreamWriter:
public class TextBoxStreamWriter : TextWriter
{
TextBox _output ;
public TextBoxStreamWriter(TextBox output)
{
_output = output;
}
public override void Write(char value)
{
MethodInvoker action =
delegate
{
_output.AppendText(value.ToString());
};
_output.BeginInvoke(action);
}
public override Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}
在我的演示者中 class:
public MTMainPresenter(IMTMainForm view)
{
_view = view;
HandleShizzle();
Console.Writeline("Presenter initialized :( "); // << Doesn't work as I want it to...
}
program.cs:
private static MTMainPresenter _presenter;
static void Main()
{
var mainForm = new MTMainForm();
_presenter = new MTMainPresenter(mainForm);
Application.Run(mainForm);
}
在我的表格中:
TextWriter _writer = null;
private void Form1_Load(object sender, EventArgs e)
{
_writer = new TextBoxStreamWriter(txtboxConsole);
Console.SetOut(_writer);
Console.Writeline("Yay !"); // << Works fine, the way I want it to
}
所以基本上,我以生成 Console.WriteLine() 的形式创建了一个测试按钮,这工作得很好。但是当我在演示器中执行相同操作时,它会写入标准调试 window。我已经尝试在 Procgram.cs class 中初始化 TextWriter,但由于它有一个 TextBox 控件,需要分配它,我对如何解决这个问题有点迷茫...
我很确定这很容易修复,但我缺乏经验。
提前致谢 P
我明白了。经过一段时间的思考并尝试了一些事情之后,我找到了一种方法来做到这一点。可能会有更好的方法,所以如果这不符合最佳实践,请纠正我。 :) 但它有效...
我现在可以在任何地方调用 Console.WriteLine()(MTMainForm、Presenter、我的 Presenter 中自定义对象的任何实例...)。
我正在做的步骤... 1. 创建表格 2. 在窗体中,创建链接到控件的编写器 3. 返回 Program.cs,从表单中获取创建的编写器 4.将输出偏离到作者 5. 运行 表格...
Program.cs
static void Main()
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var mainForm = new MTMainForm();
TextWriter wrt = mainForm.GetWriter();
Console.SetOut(wrt);
_presenter = new MTMainPresenter(mainForm);
Application.Run(mainForm);
}
MTMainForm:
TextBoxStreamWriter _writer = null;
public MTMainForm()
{
InitializeComponent();
_writer = new TextBoxStreamWriter(textBoxConsole);
}
public TextBoxStreamWriter GetWriter()
{
return _writer;
}
TextBoxStreamWriter:
public class TextBoxStreamWriter : TextWriter
{
TextBox _output;
public TextBoxStreamWriter(TextBox output)
{
_output = output;
}
public override void Write(char value)
{
MethodInvoker action =
delegate
{
_output.AppendText(value.ToString());
if (_output.Text.Length > 4000)
_output.Text = _output.Text.Substring(2000, _output.Text.Length - 2000);
};
_output.BeginInvoke(action);
}
public override Encoding Encoding
{
get { return System.Text.Encoding.UTF8; }
}
}