?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會彈出解決方法,選擇彈出的解決方式。