In this post I describe the problem when changing the screen orientation, well 2 problems and at the end the final solution for changing the screen orientation. if you just want to read about the solution, scroll down…
In order to learn how to rotate the screen orientation I watched a MSDN How To Video, which helped but didn’t give me the right solution (hence this post )
By the video, in order to change the screen orientation you would write this line:
SystemSettings.ScreenOrientation = ScreenOrientation.Angle270;
This line does change the screen orientation, the problem occurs if you also want to monitor the screen orientation change. (see How to Monitor screen orientation change) In my case I wanted my application to always be in landscape mode, meaning that in case of a screen rotation to portrait mode, I will rotate the screen back to landscape mode.
I used the SystemState change event to monitor the change and used
SystemSettings.ScreenOrientation = ScreenOrientation.Angle270;
To change the orientation back to landscape. The screen orientation indeed changed, but after this change the SystemState change event didn’t always fire, hence in some cases my application was displayed in portrait mode. the reason for this was that the SystemState.DisplayRotation didn’t change. problem…
I thought about using the resize event, and changing the SystemSettings.ScreenOrientation.. but I got an exception. the reason for the exception was that when being in the Resize function, I changed the SystemSettings.ScreenOrientation, making another call to the Resize function…
I found that other developers had the same problem, and saw 2 solutions, the first is to catch the exception and display to the user a message indication that the application dose not supports this mode, and the second was to use a timer (of 200 ms) inside the Resize(), that will change the orientation. I didn’t like both solutions… so I found a third one…
my solution:
I wanted to use the SystemState change event, since its much more efficient than the Resize event. I understood that I need to change the SystemState.DisplayRotation, but its read only…
Since the SystemState.DisplayRotation is read from the registry… I was to write the value to the registry causing it to change and hence the SystemState change event will always fire
problem solved!
note that SystemSettings.ScreenOrientation still needs to be changed, since its the parameter that decides the display orientation.
the code:
void OrientationWatcher_Changed(object sender, ChangeEventArgs args) { int newOrientation = (int)args.NewValue; if (condition on newOrientation) ChangeToLandscape(); } public static void ChangeToLandscape() { SystemSettings.ScreenOrientation = ScreenOrientation.Angle270; Registry.SetValue(@"HKEY_LOCAL_MACHINE\System\GDI\ROTATION", "Angle", 270, RegistryValueKind.DWord); }