views:

102

answers:

2

In a Windows Form, I have a search box that fires an event to search a remote database and display some results. The query is pretty fast, usually just a fraction of a second, but in case the delay is noticeable there is a progress bar and label in the form's status bar. When the user clicks "Search" the status label should appear and the progress bar show some progress. Then when the result comes back the label should disappear and the progress bar should be full. Pretty basic response.

The problem is, I can't get those actions to happen in that order. Using the code below, I click "Search", nothing happens until the results are displayed, and then the progress bar fills up from 0 to 100. The label never appears. I even threw in a sleep command immediately after the event to be sure I wasn't just missing it, but it's as if the first 2 statements are not being executed. What am I doing wrong here?

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

What does the event actually do? Does it also modify the status label and progress bar?

Also, your title doesn't make sense given your question - can you re-title or better explain what 'synchronization' you need? Thanks.

Chad
sorry, "synchronize" was a poor choice of wording here. See above comment.
Travis Christian
A: 

The code provided changes the UI attributes, but the thread can't repaint the UI until after searchButton_Click returns. So the changes made before the event are never applied, because they're overridden by the changes made after, which are then applied when the method returns.

Instead, update the UI attributes before firing the event:

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

and from the event handler, run the query in a separate thread (BackgroundWorker), so that the UI can update in the meantime:

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

then update the UI again in the method that is called when the BackgroundWorker thread completes:

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