7

I want to change form size depending on Screen and it's resolution.

What I want is a correct event to track these screen changes as well as screen resolution changes at runtime.

In other words,

  1. If user is using two screens and move application to another screen, that should be tracked and change size accordingly, i.e. reduce size if new screen's resolution is low or increase size if resolution is larger.

  2. Also track screen resolution change on the same screen, and make changes to size accordingly.

I know how to change Form size, get current screen and it's resolution, just need these events to keep track of these changes.

Indigo
  • 2,887
  • 11
  • 52
  • 83
  • 1
    As a starting point, look at [SystemEvents](http://msdn.microsoft.com/en-us/library/Microsoft.Win32.SystemEvents.aspx) class – Steve Jul 22 '13 at 14:02
  • What are you doing about the form contents? Isn't that really what is important? Simply resizing the window is less than half the fight. – DonBoitnott Jul 22 '13 at 14:30
  • @Steve: thanks, it solves half the problem, what about tracking screen change? – Indigo Jul 22 '13 at 14:48
  • @DonBoitnott: Basically, I have one main GroupBox and a Panel inside. So I am changing GroupBox and Panel size also. Everything inside wraps up in Panel and can be accessed using Scrolls. – Indigo Jul 22 '13 at 14:51
  • 1
    Fair enough. I assume then that you are trying to keep the form itself visible on all sides? Is there a bigger goal in mind? I wonder about strangeness when it occurs, such as: what happens if I am dragging the form to another monitor, and I have a hold on the TitleBar at the far-right point (next to the ControlBox), and you resize small enough for that space to disappear? What am I left holding? – DonBoitnott Jul 22 '13 at 14:54
  • @DonBoitnott: Yes correct. However, I am trying to take a pretty simple approach here. This application is slightly bigger (in height only) than small resolution laptops like the one with 768 as vertical resolution. In this case, I just simply want to reduce height of my application to make it visible well on that laptop screen and still be able to keep all controls on screen wrapped inside a panel and available through scroll. I know exact resolution of the systems on which this application is going to be used. So there is no real need to create a complex UI. – Indigo Jul 22 '13 at 15:04
  • I already have horizontal stretching locked and there is a minimum and maximum limit on vertical stretching too. Simply want to change size suitable according to current screen resolution, whenever user use two screens at the same time, one with larger resolution and another with smaller. – Indigo Jul 22 '13 at 15:04

1 Answers1

9

Going over this answer I've decided to improve it and add further information to form a more complete solution.

The Challenge

Tracking which screen a Form is currently being rendered on. This can change if a user drags the form to another monitor or unplugs a monitor. The resolution can change if a user manually drags a window to a different display or changes the resolution directly.

Firstly, tracking form location. We need to hook into a Move event for the form context, fortunately the .Net framework provides such an event, and it is named Control.Move Event.

Secondly, we will need to hook into a screen resolution changed event, we can do this with the SystemEvents.DisplaySettingsChanged event.

And putting it together, I got this:

struct Resolution
{
    public int Width;
    public int Height;
}

int previous = -1;
int current = -1;

private bool CheckScreenChanged()
{
    bool changed = false;
    current = GetScreenIndex();

    if (current != -1 && previous != -1 && current != previous) // form changed screen.
    {
        changed = true;
    }

    previous = current;

    return changed;
}

private int GetScreenIndex()
{
    return Array.IndexOf(Screen.AllScreens, Screen.FromControl(this));
}

private Resolution GetCurrentResolution()
{
    Screen screen = Screen.FromControl(this);
    Resolution res = new Resolution();
    res.Width = screen.Bounds.Width;
    res.Height = screen.Bounds.Height;

    return res;
}

private void SetResolutionLabel()
{
    Resolution res = GetCurrentResolution();
    label2.Text = String.Format("Width: {0}, Height: {1}", res.Width, res.Height);
}

private void ScreenChanged()
{
    label1.Text = "Screen " + current.ToString();
}

private void Form_Moved(object sender, System.EventArgs e)
{
    bool changed = CheckScreenChanged();
    if (changed == true)
    {
        ScreenChanged();
        SetResolutionLabel();
    }
}

public void SystemEvents_DisplaySettingsChanged(object sender, EventArgs e)
{
    SetResolutionLabel();
}

public void Initialize()
{
    this.Move += Form_Moved;
    SystemEvents.DisplaySettingsChanged += new
    EventHandler(SystemEvents_DisplaySettingsChanged);

    previous = GetScreenIndex();
    current = GetScreenIndex();
    ScreenChanged();
    SetResolutionLabel();
}

The code above is tested on a simple form with two labels called label1 and label2, which are updated when the screen the form is on changes or the resolution changes.

An image of this in action on my primary screen/display

Screen0

And on my secondary screen/display when the form has been dragged to it:

enter image description here

Daniel Lane
  • 2,575
  • 2
  • 18
  • 33
  • thanks, I did it and working well. Although, still the question remains, how to track screen change(point 1 in question). – Indigo Jul 22 '13 at 14:49
  • I don't think you made a correct keywords search, the OP wants to know when the screen is changed (in a multi-screen system), he wants to know the event which can notify the screen switching not to detect the resolution by monitor. – King King Jul 22 '13 at 16:32
  • 1
    "Because this is a static event, you must detach your event handlers when your application is disposed, or memory leaks will result." [SystemEvents.DisplaySettingsChanged Event](https://learn.microsoft.com/en-us/dotnet/api/microsoft.win32.systemevents.displaysettingschanged?view=dotnet-plat-ext-3.1) – TechAurelian Jul 23 '20 at 06:18