2010-06-15 1 views
2

В форме Windows у меня есть окно поиска, в котором происходит событие для поиска удаленной базы данных и отображения некоторых результатов. Запрос выполняется довольно быстро, как правило, всего лишь часть секунды, но в случае заметности задержки есть индикатор выполнения и метка в строке состояния формы. Когда пользователь нажимает «Поиск», должна появляться метка состояния, а индикатор выполнения показывает некоторый прогресс. Затем, когда результат возвращается, метка должна исчезнуть, а индикатор выполнения должен быть заполнен. Довольно основной ответ.Обновление ToolStripProgressBar и ToolStripStatusLabel вместе с действием

Проблема в том, что я не могу заставить эти действия произойти в этом порядке. Используя приведенный ниже код, я нажимаю «Поиск», ничего не происходит до тех пор, пока результаты не будут отображаться, а затем индикатор выполнения заполнится от 0 до 100. Метка никогда не появляется. Я даже бросил команду сна сразу после события, чтобы быть уверенным, что я просто не пропустил его, но это похоже на то, что первые два оператора не выполняются. Что я здесь делаю неправильно?

private void searchButton_Click(object sender, EventArgs e) 
    { 
     toolStripStatusLabel1.Visible = true; 
     toolStripProgressBar1.Value = 20; 
     m_changeRequestedEvents.Fire<String>("SearchTerm", searchTextBox.Text); 
     toolStripProgressBar1.Value = 100; 
     toolStripStatusLabel1.Visible = false; 
    } 
+0

Использует ли этот метод Fire другой поток для запроса базы данных? Если нет, причина, по которой вы никогда не видите ярлык, - это то, что вы делаете все в одном потоке. В Windows Forms основной поток несет полную ответственность за покраску окон и содержимого. Если он повесил приложение ADO.NET, то он не может нормально перерисовывать этикетку. К тому времени, когда он вернется к событиям компоновки/рисования элементов управления, он уже выполнит запрос и вернет его к невидимому. –

+0

Нет, это однопоточное приложение. Событие запускает запрос БД из другого класса, который затем запускает другое событие в пользовательском интерфейсе для обновления таблицы результатов. Я понимаю, что он не может перерисовать, когда он запускает запрос, но, учитывая приведенный выше код, я бы подумал, что он будет частично заполнять панель и отображать ярлык * до того, как он будет делать бэкэнд-материал, а затем выполнить последние 2 строки после того, законченный. –

+2

Пользовательский интерфейс не будет обновляться до тех пор, пока не будет выполнен поискButton_Click(). Вам нужно запустить Query в другом потоке. Посмотрите на BackgroundWorker. –

ответ

1

код при условии изменения атрибутов UI, но поток не может перекрасить UI, пока после того, как searchButton_Click возвращается. Таким образом, изменения, внесенные до события, никогда не применяются, поскольку они переопределяются изменениями, внесенными после, которые затем применяются, когда метод возвращается.

Вместо обновление пользовательского интерфейса атрибутов перед обжигом события:

searchButton.Enabled = false; 
toolStripProgressBar1.Value = 0; 
toolStripStatusLabel1.Visible = true; 
m_changeRequestedEvents.Fire<String>("SearchTerm", searchTextBox.Text); 

и из обработчика событий, выполнить запрос в отдельном потоке (BackgroundWorker), так что пользовательский интерфейс может обновляться в то же время:

private void View_OnSearchTermChangeRequest(Object sender, PropertyChangeRequestEventArgs<String> args) 
{ 
    m_search_bgw = new BackgroundWorker(); 
    ... 
    m_DBHandler.current_worker = m_search_bgw; 
    m_search_bgw.RunWorkerAsync(args.RequestedValue); 
} 

затем обновить пользовательский интерфейс снова в методе, который вызывается, когда поток BackgroundWorker завершает:

void UpdateView(DataView projects) 
{ 
    dataGridView1.DataSource = projects; 
    ... 
    toolStripProgressBar1.Value = 100; 
    toolStripStatusLabel1.Visible = false; 
}