【问题标题】:Keep track of screen change and screen resolution change in Windows Form Application to change form size跟踪 Windows 窗体应用程序中的屏幕更改和屏幕分辨率更改以更改窗体大小
【发布时间】:2013-07-22 13:55:17
【问题描述】:

我想根据屏幕和分辨率更改表单大小。

我想要的是一个正确的事件来跟踪这些屏幕变化以及运行时屏幕分辨率的变化。

换句话说,

  1. 如果用户正在使用两个屏幕并将应用程序移动到另一个屏幕,则应对其进行跟踪并相应地更改大小,即如果新屏幕的分辨率较低则减小尺寸,或者如果分辨率较大则增大尺寸。

  2. 还可以跟踪同一屏幕上的屏幕分辨率变化,并相应地更改大小。

我知道如何更改表单大小、获取当前屏幕及其分辨率,只需要这些事件来跟踪这些更改。

【问题讨论】:

  • 作为起点,看SystemEvents
  • 你对表单内容做了什么?这真的不重要吗?简单地调整窗口大小还不到一半。
  • @Steve:谢谢,它解决了一半的问题,那么跟踪屏幕变化呢?
  • @DonBoitnott:基本上,我有一个主要的 GroupBox 和一个 Panel 里面。所以我也在改变 GroupBox 和 Panel 的大小。里面的所有东西都包含在 Panel 中,可以使用 Scrolls 访问。
  • 很公平。我假设您正在尝试使表单本身在所有方面都可见?有没有更大的目标?我想知道当它发生时会发生什么奇怪的事情,例如:如果我将表单拖到另一个监视器上,并且我在最右边的点(ControlBox 旁边)按住 TitleBar,并且你调整的大小足够小那个空间消失?我还剩下什么?

标签: c# winforms screen


【解决方案1】:

查看此答案后,我决定对其进行改进并添加更多信息以形成更完整的解决方案。

挑战

跟踪当前正在呈现表单的屏幕。如果用户将表单拖到另一个监视器或拔下监视器,这可能会改变。如果用户手动将窗口拖动到不同的显示器或直接更改分辨率,分辨率可能会更改。

首先,跟踪表单位置。我们需要为表单上下文挂钩一个 Move 事件,幸运的是 .Net 框架提供了这样一个事件,它被命名为Control.Move Event

其次,我们需要挂钩到屏幕分辨率更改事件,我们可以通过 SystemEvents.DisplaySettingsChanged 事件来做到这一点。

把它放在一起,我得到了这个:

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();
}

上面的代码是在一个简单的表单上测试的,它有两个标签 label1 和 label2,当表单所在的屏幕改变或分辨率改变时,它们会更新。

在我的主屏幕/显示器上运行此图像

当表单被拖到它时,在我的辅助屏幕/显示器上:

【讨论】:

  • 谢谢,我做到了,而且工作得很好。虽然,问题仍然存在,如何跟踪屏幕变化(有问题的第 1 点)。
  • 我认为你没有正确搜索关键字,OP想知道屏幕何时改变(在多屏系统中),他想知道可以通知屏幕的事件切换不通过显示器检测分辨率。
  • “因为这是一个静态事件,所以当你的应用程序被释放时,你必须分离你的事件处理程序,否则会导致内存泄漏。” SystemEvents.DisplaySettingsChanged Event
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-03-04
  • 1970-01-01
  • 2012-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多