Rawns Rawns - 1 year ago 61
C# Question

Order buttons that represent attached monitors by Windows Display order

I have the below code to draw a button(s) onto a panel for each monitor that is currently connected to the PC.

var padding = 5;
var buttonSize = new Size(95, 75);
for (int i = 0; i < Screen.AllScreens.Length; i++)
var screen = Screen.AllScreens[i];
Button monitor = new Button
Name = "Monitor" + screen,
AutoSize = true,
Size = buttonSize,
Location = new Point(12 + i * (buttonSize.Width + padding), 14),
BackgroundImageLayout = ImageLayout.Stretch,
BackgroundImage = Properties.Resources.display_enabled,
TextAlign = ContentAlignment.MiddleCenter,
Font = new Font("Segoe UI", 10, FontStyle.Bold),
ForeColor = Color.White,
BackColor = Color.Transparent,
Text = screen.Bounds.Width + "x" + screen.Bounds.Height


For devices with one or more monitors attached, the code works just fine and this is the end result:

enter image description here

However, while it works, I'd like to (if possible) order them as they appear in the Windows display view:

enter image description here

In the first screenshot, they are ordered as 2 | 3 | 1 instead of 3 | 2 | 1.

Is what I'm after possible?

Answer Source

Multiple screens in Windows are handled as one, big, "glued" working area. Based on that, order of screens in configuration is according to their position in the new working area. Assuming that all of your screens are in one line, you can just use


as ordering property. If the screens are layed out in multiple rows, then ordering will also have to consider Y component.

EDIT: You could just use Linq for sorting, specifically OrderBy(). Example usage for case when screens are in one row and collection will be iterated once.


for (int i = 0; i < Screen.AllScreens.Length; i++)
   var screen = Screen.AllScreens[i];


foreach(var screen in Screen.AllScreens.OrderBy(i => i.Bounds.X))