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 buttonを押すと、program.csはいくつかのタスクを実行し、Console.WriteLine()
を使用して進行状況をコンソールに常に出力します(コマンドプロンプト)。
質問:コマンドプロンプトに印刷する代わりに、form1のテキストボックスに印刷するにはどうすればよいですか?ユーザーの操作なしで進行状況を常に印刷する必要があります。
前もって感謝します!
ちなみに、それはテキストボックスである必要はなく、ラベルまたはテキストを受け取ることができる他のものにすることができます。私がより理にかなっているので、私はテキストボックスを選びました。
テキストボックスへの書き込みが可能な新しいTextWriter
を作成することから始めます。唯一の必要Write
を受け入れる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; }
}
}
次に、これを使用して次のことができます。
Console.SetOut(new MultiTextWriter(new ControlWriter(textbox1), Console.Out));
私はリストボックスにこのようなsthを使用します:
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);
動作するかどうかはわかりませんが、コンソール出力をリダイレクトしてみてください。
Console.SetOut()
を使用し、WriteLine()
メソッドをオーバーライドするTextWriter
の派生物を作成し、メソッドパラメーターをTextBox.Text
動作するはずです。