2012-03-23 3 views
1

У меня есть TextBox в моем приложении, что он используется для отображения состояния процесса. Что-то вроде этогоTextBox, заполняющий C#

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

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

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

+1

Какой интерфейс пользовательского интерфейса вы используете? Windows Forms, WPF, ASP.Net? – Botz3000

+1

Это связано с тем, что вы блокируете основной поток внутри цикла for (который отвечает за рисование и обновление вашей формы). Вам нужно будет отключить отдельный рабочий поток для обработки ваших данных и отправки сообщений в вашу основную форму, чтобы обновить текстовое поле, чтобы ваш основной поток оставался свободным для обновления. –

+0

Проблема решена. Я знаю о BackgroundWorker, но искал более простое решение, например Application.DoEvents(). Спасибо всем за быстрые ответы. – user1288050

ответ

0

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

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

EDIT: Кто-то изменил этот вопрос без объяснения причин. Это было бы справедливо. Вопрос о плакате знал о backroundworker и хотел более простое решение.

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

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

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

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

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

0

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

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

0

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

0

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

2
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

Вы должны использовать BackgroundWorker обновить графический интерфейс из другого потока и оставьте GUI работает для себя (как вы можете делать другие вещи в GUI, как нажав флажки или просмотр других вещей). Затем вы используете метод 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(); 
     } 
    } 
}