C# 界面检测显示器移除并在可用显示器上显示
C# 检测显示器被移除,将界面在当前可用的显示器上显示,避免程序在任务栏点击无响应。
using System;
using System.Linq;
using System.Windows.Forms;public class MonitorWatcher : IDisposable
{private readonly Form _targetForm;private Screen _currentScreen;private bool _disposed = false;public MonitorWatcher(Form form){_targetForm = form ?? throw new ArgumentNullException(nameof(form));_currentScreen = GetCurrentScreen();// 订阅显示器变化事件SystemEvents.DisplaySettingsChanged += OnDisplaySettingsChanged;}private Screen GetCurrentScreen(){if (!_targetForm.IsHandleCreated || _targetForm.WindowState == FormWindowState.Minimized){return Screen.PrimaryScreen;}return Screen.FromHandle(_targetForm.Handle);}private void OnDisplaySettingsChanged(object sender, EventArgs e){// 检查当前显示器是否仍然存在var allScreens = Screen.AllScreens;bool currentScreenExists = allScreens.Any(s => s.DeviceName == _currentScreen.DeviceName);if (!currentScreenExists){// 当前显示器已移除,迁移到其他显示器MoveToAvailableScreen();}// 更新当前显示器信息_currentScreen = GetCurrentScreen();}private void MoveToAvailableScreen(){var availableScreens = Screen.AllScreens;if (availableScreens.Length == 0){return; // 没有可用显示器}// 选择最合适的显示器(优先主显示器)var targetScreen = availableScreens.FirstOrDefault(s => s.Primary) ?? availableScreens[0];// 计算新位置,确保窗口完全可见var newLocation = CalculateNewPosition(_targetForm, targetScreen);// 移动窗口_targetForm.Location = newLocation;// 如果窗口最大化,先恢复再移动再最大化if (_targetForm.WindowState == FormWindowState.Maximized){_targetForm.WindowState = FormWindowState.Normal;_targetForm.Location = newLocation;_targetForm.WindowState = FormWindowState.Maximized;}}private Point CalculateNewPosition(Form form, Screen screen){// 确保窗口完全在目标显示器的工作区域内Rectangle workingArea = screen.WorkingArea;int newX = workingArea.Left;int newY = workingArea.Top;// 如果窗口大小超过工作区,调整大小if (form.Width > workingArea.Width){form.Width = workingArea.Width;}if (form.Height > workingArea.Height){form.Height = workingArea.Height;}return new Point(newX, newY);}public void Dispose(){if (!_disposed){SystemEvents.DisplaySettingsChanged -= OnDisplaySettingsChanged;_disposed = true;}}
}
调用例子方法
using System;
using System.Windows.Forms;public partial class MainForm : Form
{private MonitorWatcher _monitorWatcher;public MainForm(){InitializeComponent();// 初始化显示器监控_monitorWatcher = new MonitorWatcher(this);// 窗体关闭时释放资源this.FormClosed += (s, e) => _monitorWatcher.Dispose();}
}
如果遇到没有定义的类,使用右键“快速操作和重构...” vs会弹出解决方法,选择弹出的解决方式。