开发者

How to update check boxes in a .NET checkListBox?

开发者 https://www.devze.com 2023-01-04 08:08 出处:网络
I\'ve run into a problem where I want to display a list of items in a checkListBox and programmatically check them off one by one as each process I am monitoring gets completed.

I've run into a problem where I want to display a list of items in a checkListBox and programmatically check them off one by one as each process I am monitoring gets completed.

I will try to water my code down to the bare essentials so everyone can easily grasp what is happening.

for (int i = 0; i < 10; i++)
{
    SOME_FUNCTION();
    progressBar.Value++;
    checkListBoxItems.SetItemCheckState(i, CheckState.Checked);
}

This is essentially what my code is doing. The progress bar gets updated while the loop is running, but all of the check boxes do not get checked until the loop is finished and they are all checked at the same time.

This 开发者_运维问答obviously defeats the purpose of displaying the check boxes and I was curious if there was something I was missing that allows you to refresh the checkListBox control, or something similar.

I apologize if this question seems vague, I seem to have that problem quite often here.


This is standard behavior for any Windows GUI application, screen updates don't happen until the UI thread goes idle so that Windows can deliver the Paint event. One of the absolute worst things you could do is calling Application.DoEvents(). Yes, that will deliver the Paint event. But it also allows your user to close the form. That produces a Big Kaboom when the control you are trying to update is suddenly not there anymore. Your loop is still running, but the form isn't there anymore.

What you must have noticed is that the progress bar actually updated but the CheckedListBox did not. That's because ProgressBar often is used to show progress when the code is in a loop, so it makes sure that when you change the Value property, it immediately paints itself without waiting for Windows to tell it that it needs to be repainted. Dirty trick, very confusing.

But you can take advantage of that trick as well, it is easy. Modify your code like this:

for (int i = 0; i < 10; i++)
{
    SOME_FUNCTION();
    progressBar.Value++;
    checkListBoxItems.SetItemCheckState(i, CheckState.Checked);
    checkListBoxItems.Update();
}

The Update() method means "paint yourself when necessary". It is, you changed the check state of an item. Never does the Big Kaboom thingy on you, the user can't suddenly make the control disappear.

If SOME_FUNCTION() takes a long time, like more than 10 x 0.3 seconds or so, then you should start thinking about using threads.


You can call Invalidate() on the control you need to have repainted.

So something like this every time you update a check mark in the list:

checkListBoxItems.Invalidate();

Enjoy!


for (int i = 0; i < 10; i++)
{
    SOME_FUNCTION();
    progressBar.Value++;
    checkListBoxItems.SetItemCheckState(i, CheckState.Checked);
    Application.DoEvents();
}
0

精彩评论

暂无评论...
验证码 换一张
取 消