C# WinForm程序ArgumentException未处理:桌面截图显示鼠标位置报错
问题原因及解决方案
你遇到的ArgumentException(参数无效),核心原因是MouseMove事件中的临时Bitmap被提前释放:
代码里用using(Bitmap bmTemp = ...)包裹临时位图,当using块执行完毕时,bmTemp会被自动调用Dispose()释放资源,但此时你已经将它赋值给了picDesktop.Image。窗体渲染时尝试访问已释放Bitmap的Width属性,就会触发参数无效的异常。
修正后的代码
1. 修复MouseMove事件处理程序
移除临时Bitmap的using包裹,同时每次赋值新位图前释放旧资源,避免内存泄漏:
private void PictureBox_MouseMove(object sender, MouseEventArgs e) { try { // 创建临时Bitmap,不使用using,交给PictureBox持有引用 Bitmap bmTemp = new Bitmap(ScreenCaptureBitmap); using (Graphics gr = Graphics.FromImage(bmTemp)) { Brush theBrush = SystemBrushes.FromSystemColor(SystemColors.WindowText); gr.DrawString($"({e.X}, {e.Y})", this.Font, theBrush, e.X + 10, e.Y - 30); } // 先释放原有Image资源,再赋值新位图 picDesktop.Image?.Dispose(); picDesktop.Image = bmTemp; } catch (Exception ex) { MessageBox.Show(ex.Message); } }
2. 优化窗体构造函数(可选)
补充空引用判断,避免创建资源失败时触发额外异常:
public partial class Form1 : Form { Bitmap ScreenCaptureBitmap = null; public Form1() { InitializeComponent(); this.FormBorderStyle = FormBorderStyle.None; this.WindowState = FormWindowState.Maximized; picDesktop.Dock = DockStyle.Fill; picDesktop.MouseMove += PictureBox_MouseMove; var screenBounds = Screen.PrimaryScreen.Bounds; Graphics graphics = null; try { ScreenCaptureBitmap = new Bitmap(screenBounds.Width, screenBounds.Height); graphics = Graphics.FromImage(ScreenCaptureBitmap); graphics.CopyFromScreen(screenBounds.Location, Point.Empty, screenBounds.Size); picDesktop.Image = ScreenCaptureBitmap; } catch (Exception ex) { MessageBox.Show(ex.Message); } finally { // 加空判断,防止graphics未初始化时调用Dispose报错 graphics?.Dispose(); } } }
关键说明
- 移除
using是因为PictureBox需要持续持有Bitmap引用,直到下次替换或窗体关闭 - 每次赋值新Image前调用
picDesktop.Image?.Dispose(),是为了及时释放旧位图资源,避免内存持续增长 - 构造函数中的
graphics?.Dispose(),是防止Bitmap创建失败时,graphics为null触发空引用异常
内容的提问来源于stack exchange,提问作者Derek Johnson
相关产品推荐
相关产品推荐

