Keeping yourself out of trouble using SystemEvents
Why do we need both SystemEvents.UserPreferenceChanging and SystemEvents.UserPreferenceChanged?
The idea behind this is that if you have some object cached (say a brush based on a SystemColor), you would change the cache on UserPreferenceChanging. The items that would refer to that cache (say a control painting its background) would sync UserPreferenceChanged and force a repaint.
Static events and you.
Note, this is a static event, I've said it before, but it's so subtle an issue - bear with me for repeating. If you're hooking to any of the SystemEvents, make sure to unhook from them when you're through.
Why? When your object subscribes to a static event it gets stored into a static event handler list, holding onto your object so it can call the object's method when the time is right. If you dont unsubscribe from the event, two things will happen (neither of which you want).
1. Your object can be called on its event handler even after you dispose it
2. Your object will not be able to be finalized until the application exits because the static event handler list (which wont go away until exit) is keeping a strong reference to your object.
The simplest way to fix this is to unsubscribe in the Dispose method. If you want to see the pattern for using UserPreferenceChanged, there's some code here.
SystemEvents and threading
If you have more than one thread going, you may find in v1.0 and v1.1 that UserPreferenceChanged and UserPreferenceChanging can call back on the wrong thread. In v2.0 we have made some improvements in this area to fire the events on the main thread.
If you are using these events in previous versions of the framework, you may want to consider checking the InvokeRequired flag, then using Control.Invoke or Control.BeginInvoke to update your UI. More details about Invoke/BeginInvoke here and here.