web-dev-qa-db-fra.com

Redirection de Console.WriteLine () vers la zone de texte

Je construis cette application dans Visual Studio 2010 en utilisant C #.

En gros, il y a 2 fichiers, form1.cs (qui est le formulaire Windows) et program.cs (où se trouve toute la logique).

//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.");
        }
    }
}

Il y a un bouton Exécuter et une zone vide textbox.

Lorsque l'utilisateur clique sur le bouton Exécuter , program.cs effectue une tâche et imprime constamment la progression à l'aide de Console.WriteLine() sur la console (invite de commande).

Question: Comment puis-je imprimer dans la zone de texte sur formulaire1 au lieu d’être imprimé dans une invite de commande?.

Merci d'avance!

En passant, il n'est pas nécessaire que ce soit une zone de texte, cela peut être une étiquette ou autre chose pouvant prendre du texte. J'ai choisi textbox parce que cela me semble plus logique.

18
sora0419

Commencez par créer une nouvelle TextWriter capable d’écrire dans une zone de texte. Il suffit que nécessite de remplacer la méthode Write qui accepte une char, mais cela serait inefficace, il est donc préférable de remplacer au moins la méthode par une chaîne.

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; }
    }
}

Dans ce cas, je l’ai accepté simplement une Control, qui pourrait être une Textbox, une Label ou autre chose. Si vous voulez le changer en une Label, ce serait bien.

Ensuite, définissez simplement la sortie de la console sur une nouvelle instance de ce rédacteur, en pointant sur une zone de texte ou une étiquette:

Console.SetOut(new ControlWriter(textbox1));

Si vous voulez que le résultat soit écrit sur la console ainsi que dans la zone de texte, nous pouvons utiliser cette classe pour créer un rédacteur capable d'écrire sur plusieurs rédacteurs:

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; }
    }
}

Ensuite, en utilisant ceci, nous pouvons faire:

Console.SetOut(new MultiTextWriter(new ControlWriter(textbox1), Console.Out));
42
Servy

J'utilise qc comme ceci pour une listbox:

    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();
    }
}

et dans mon application principale:

_writer = new ListBoxWriter(DebugWin); // DebugWin is the name og my listbox

Console.SetOut (_writer);

2
user38723

Je ne sais pas si cela fonctionnera, mais vous pouvez essayer de rediriger la sortie de la console.

Utilisez Console.SetOut() et créez un dérivé de TextWriter qui remplace la méthode WriteLine() et affectez simplement le paramètre de méthode à votre TextBox.Text Devrait fonctionner.

0
quirell