Перенаправление Console.WriteLine() в текстовое поле
Я создаю это приложение в Visual Studio 2010 с помощью С#.
В основном есть 2 файла, form1.cs(это форма окна) и 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()
на консоли (командной строке).
Вопрос. Как я могу печатать в текстовое поле формы1 вместо печати в командной строке?
Мне нужно будет печатать прогресс постоянно без каких-либо действий пользователя.
Спасибо заранее!
Кстати, он не обязательно должен быть текстовым полем, это может быть ярлык или что-то еще, что может принимать текст. Я выбрал текстовое поле, потому что это имеет для меня больше смысла.
Ответы
Ответ 1
Начните с создания нового 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
, a 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));
Ответ 2
Я использую 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);
Ответ 3
Не знаю, будет ли это работать, но вы можете попробовать перенаправить вывод консоли.
Используйте Console.SetOut()
и создайте производную от TextWriter
, которая переопределяет метод WriteLine()
и просто назначает параметр метода вашему TextBox.Text
Должен работать.
Ответ 4
поместите textbox
в форму (multiple lines
enabled) или текстовую область, которую вы можете сделать в своем цикле
txtOutput.Text += "Progress " + percent + "% completed." + Environment.NewLine();