Заполнение TextBox в C # - PullRequest
       55

Заполнение TextBox в C #

1 голос
/ 23 марта 2012

У меня в приложении есть TextBox, который используется для отображения состояния процесса. Как то так

for(...)
  textbox.text = "new line \r\n" + textbox.text

Проблема в том, что когда он заполняется, текст не виден, только белый фон. Когда процесс завершен, тогда весь добавленный текст виден. Любой вариант, как решить эту проблему (мне нужно, чтобы текст был виден в течение всего процесса).

Большое спасибо.

Ответы [ 6 ]

2 голосов
/ 23 марта 2012
public partial class Form1 : Form
{
    public Form1()
    {
        InitializeComponent();

        BackgroundWorker bg = new BackgroundWorker();
        bg.DoWork += new DoWorkEventHandler(bg_DoWork);
        bg.RunWorkerAsync();
    }


    delegate void Temp();
    void bg_DoWork(object sender, DoWorkEventArgs e)
    {
        Temp temp = new Temp(UpdateTextBox);

        while (true)
        {
            Thread.Sleep(1000);
            textBox1.BeginInvoke(temp);

        }
    }

    void UpdateTextBox()
    {
        textBox1.Text += "+";
    }
}
0 голосов
/ 23 марта 2012

Вам необходимо использовать BackgroundWorker для обновления вашего графического интерфейса из другого потока и оставить графический интерфейс работающим на себя (как вы можете делать другие вещи внутри графического интерфейса, такие как нажатие флажков или просмотр других вещей).Затем вы используете метод LogBoxTextAdd для обновления TextBox из другого потока, чтобы он не вызывал ошибку Cross-Thread.

using System;
using System.ComponentModel;
using System.Windows.Forms;

namespace WindowsFormsApplication4 {
    public partial class Form1 : Form {
        private readonly BackgroundWorker bg = new BackgroundWorker();
        public Form1() {
            InitializeComponent();
            bg.DoWork += doWork;
        }
        private void doWork(object sender, DoWorkEventArgs e) {
            for (int i = 0; i < 15; i++) {
                LogBoxTextAdd("TEST");
            }
        }
        private void LogBoxTextAdd(string varText) {
            if (InvokeRequired) {
                textBox1.Invoke(new MethodInvoker(() => LogBoxTextAdd(varText)));
            } else {
                textBox1.Text = varText + "\r\n" + textBox1.Text;
            }
        }
        private void button1_Click(object sender, EventArgs e) {
            bg.RunWorkerAsync();
        }
    }
}
0 голосов
/ 23 марта 2012

Ваш цикл блокирует основной поток пользовательского интерфейса. Поэтому, как только управление выходит из цикла, пользовательский интерфейс обновляется сразу. Я думаю, что вы должны использовать BackgroundWorker здесь. Ваша проблема хорошо обсуждается в этой статье . Надеюсь, это поможет.

0 голосов
/ 23 марта 2012

Используйте многопоточность, чтобы обновить текстовое поле. В вашем коде обновления происходят слишком быстро, поэтому вы видите только белый фон.

0 голосов
/ 23 марта 2012

Это связано с тем, что пользовательский интерфейс обновляется только после завершения метода, а насос сообщений очищается для проверки на наличие сообщений «refresh».

Вы можете использовать Application.DoEvents () в конце цикла.

0 голосов
/ 23 марта 2012

Если это winforms, добавьте Application.DoEvents(); в цикл, чтобы ваше приложение могло обновить пользовательский интерфейс.

Это самый простой, но не оптимальный способ сделать это.

РЕДАКТИРОВАТЬ: Кто-то отклонил этот вопрос без объяснения причин. Это было бы справедливо. Афиша с вопросом знала о backroundworker и хотела получить более простое решение.

В любом случае, это решение может быть идеальным в зависимости от характера цикла. Если это цикл с большим количеством итераций, каждая из которых занимает короткое время, вызов Application.DoEvents () будет работать отлично. Я знаю это по собственному опыту. Поскольку это цикл, вполне возможно, что это так. Или, возможно, можно добавить несколько DoEvents () внутри цикла. Он просто проверяет очередь сообщений Windows и посещает незавершенную работу.

Я не вижу необходимости, чтобы пользователь продолжал работать над другими частями приложения.

Если это цикл с несколькими итерациями и выполнение каждого из них занимает очень много времени, необходимо выполнить его с использованием потоков.

Но помните, что новичок может совершать ошибки, если он использует потоки, не зная очень хорошо о его последствиях (я имею в виду безопасность потоков). Что делать, если приложение заходит в тупик? Как насчет разрушения не поточно-безопасных структур, используемых из разных потоков? Что если пользователь закроет главное окно, пока фоновый поток еще не закончил? Давайте будем серьезными, этот инструмент может быть бомбой в неопытных руках.

Кроме того, если вы хотите использовать многопоточность, BackgroundWorker - не единственное решение.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...