Is the event argument that’s passed to an event handler/handler override always a non-changing snapshot taken the moment the event occurred?
No! While convention suggests a “yes” answer, no technical constrain enforces this assumption (as I discovered recently). The properties of an event argument can (and sometimes do) return information about the current (live) state of the system instead of describing the moment the event occurred.
In the following example, notice how e.ButtonState changes from Pressed to Released. If e were a snapshot of the state existing at the moment the event occurred, e.ButtonState would not change within the handler. But it does. Why? Each call to e.ButtonState returns the button’s current (live) state as reported by the appropriate MouseDevice (thanks to Microsoft’s Bob Bao for pointing this out).
public class ExampleItemsControl : ItemsControl { protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e) { // Before the MessageBox's display, e.ButtonState == MouseButtonState.Pressed. MessageBox.Show("OnPreviewMouseLeftButtonDown"); // After the MessageBox's display, e.ButtonState == MouseButtonState.Released. // This call will not work as expected because base will think that the mouse // button has been released. base.OnPreviewMouseLeftButtonDown(e); } }