Awesome Windows Forms message pump trick...
So WinForms does a great job of giving you a bunch of cool events to hook into your UI. One of my favorites is quickly coming to be synchronizing the TreeView and ListBox classes. So often you have some form of directory structure or hierarchical data that you need a TreeView for, and then some expanded version of that data to go over into the ListBox. I've been blasting out a really cool picture viewer, so in my case, directories on the left, pictures on the right.
So I want a responsive UI. I want my mouse wheel to immediately allow me to scroll the ListBox after I've populated it based on the tree view. However, if you throw a Focus call into the AfterSelect, the ListBox gets focus, and then the TreeView calls Focus and get's its focus back. This is kind of crappy, but there is a way to put your own messages on the message pump. You see, BeginInvoke in Windows Forms is implemented using a special windows message. Basically, when you BeginInvoke, a message is sent to your window, and when that message is received (on the UI thread none-the-less), it notifies the Control to call some delegate that you've specified. Pretty cool huh? I think so. So why BeginInvoke and not just Invoke? Well, Invoke I believe does the same thing. However, it is synchronous, and so it executes inside of your current method (in our case the event handler for AfterSelect). So again, the ListBox gets selected and then after our event handler exits, the TreeView does a Focus call again. What we need is a way for the TreeView to call it's focus and then have our own Focus method be called. Taking advantage of the message pump is just the way, because all of our code is going to execute, and then later on down the road when some time is freed up, the message pump will kick in and process our request. To do this we'll need the appropriate delegates. WinForms already defines a MethodInvoker, that does a void return and takes no arguments. We'll create a new delegate, BoolMethodInvoker that returns a boolean instead.
private delegate bool BoolMethodInvoker();
Easy enough. Now, remember, don't call Invoke on it, since that'll run the message pump synchronously. We want to wait until after the tree has given itself focus for ours to run, so simply add the message to the pump and then return to our program execution.
listPictures.BeginInvoke(new BoolMethodInvoker(listPictures.Focus));
I've used this method countless times and it has only hit me as of late that it might be useful to others. I remember getting around some weird issues in the GDN Workspaces WinForms control using just this code, so it was definitely useful there. I highly recommend defining invoker delegates for all the method types you might want to call this way. Just remember, that when using this, you never know when the method is actually going to execute. You simply need to wait for the message pump to come around and service your message before your delegate is going to be called.