vb.net PictureBox 在 Tab 键按下时抛出“参数无效” ArgumentException
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13912367/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PictureBox throws "Parameter is not valid" ArgumentException upon tab keypress
提问by gubbfett
I have a form where the user can first scan to a bitmap. When scan is done, and the bitmap is loaded, I have 4 text boxes that are then enabled. Next to each text box, I have a button called "Cut from image". When the user clicks the button, they can click and drag in the bitmap to get the selected text using MODI.
我有一个表单,用户可以先扫描到位图。扫描完成并加载位图后,我将启用 4 个文本框。在每个文本框旁边,我有一个名为“从图像剪切”的按钮。当用户单击按钮时,他们可以在位图中单击并拖动以使用 MODI 获取选定的文本。
This works perfect except for one annoying bug: When I click a "Cut from image" button and drag a square, it gets the information nicely to the text box. Then, if i click to the next text box, it goes very well, but if I use the tab key to leave the field, I get a "Parameter is not valid" ArgumentExceptionand it does not show any help for where in the code the crash is made. I can tab around in the form with no problems at all, but once the bitmap is scanned, it crashes like 9 out of 10 times when I use the tab key.
除了一个烦人的错误外,这很完美:当我单击“从图像剪切”按钮并拖动一个正方形时,它会很好地将信息发送到文本框。然后,如果我点击下一个文本框,它运行得很好,但是如果我使用 Tab 键离开该字段,我会收到一个“参数无效”ArgumentException并且它没有显示任何帮助说明代码中的位置崩溃了。我可以毫无问题地在表单中使用 Tab,但是一旦位图被扫描,当我使用 Tab 键时,它会像 10 次中的 9 次一样崩溃。
I tried to override the tab key (just for debugging) using this:
我尝试使用以下方法覆盖 Tab 键(仅用于调试):
Protected Overrides Function ProcessTabKey(ByVal forward As Boolean) As Boolean
MsgBox("TAB is currently disabled!")
Return False 'Tried True as well, just in case
End Function
...but it still crashes.
...但它仍然崩溃。
Any suggestions about what's wrong? Since I don't know where to begin debugging I can't tell what code to show.
关于出了什么问题的任何建议?因为我不知道从哪里开始调试,所以我不知道要显示什么代码。
EDIT 1
编辑 1
Here is the stack trace for the ArgumentExceptionthat gets thrown:
这是ArgumentException抛出的堆栈跟踪:
- at System.Drawing.Image.get_Width()
- at System.Drawing.Image.get_Size()
- at System.Windows.Forms.PictureBox.ImageRectangleFromSizeMode(PictureBoxSizeMode mode)
- at System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
- at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
- at System.Windows.Forms.Control.WmPaint(Message& m)
- at System.Windows.Forms.Control.WndProc(Message& m)
- at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
- at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
- at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
- at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
- at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
- at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
- at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
- at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
- at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
- at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
- at ORC_Testing.My.MyApplication.Main(String[] Args) in 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
- at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
- at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
- at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
- at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
- at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
- at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
- at System.Threading.ThreadHelper.ThreadStart()
- 在 System.Drawing.Image.get_Width()
- 在 System.Drawing.Image.get_Size()
- 在 System.Windows.Forms.PictureBox.ImageRectangleFromSizeMode(PictureBoxSizeMode 模式)
- 在 System.Windows.Forms.PictureBox.OnPaint(PaintEventArgs pe)
- 在 System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 层)
- 在 System.Windows.Forms.Control.WmPaint(Message&m)
- 在 System.Windows.Forms.Control.WndProc(Message&m)
- 在 System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
- 在 System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
- 在 System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
- 在 System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
- 在 System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
- 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 原因,ApplicationContext 上下文)
- 在 System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 原因,ApplicationContext 上下文)
- 在 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.OnRun()
- 在 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
- 在 Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(String[] commandLine)
- 在 ORC_Testing.My.MyApplication.Main(String[] Args) 在 17d14f5c-a337-4978-8281-53493378c1071.vb:line 81
- 在 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
- 在 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
- 在 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
- 在 System.Threading.ThreadHelper.ThreadStart_Context(对象状态)
- 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
- 在 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
- 在 System.Threading.ThreadHelper.ThreadStart()
EDIT 2
编辑 2
Here is how I'm scanning/loading the image:
这是我扫描/加载图像的方式:
Dim filename As Collection
filename = TwainHandler.ScanImages("c:\scan\", "tif")
Dim ScannedFile As Image = Image.FromFile(filename(1))
PictureBox1.Image = ScannedFile
PictureBox1.Width = ScannedFile.Width
' etc.
回答by Steven Doggart
Your problem is likely that, at some point, you are calling the Disposemethod on one of your Imageobjects. When you call Image.Dispose, it deletes the underlying image data from memory, so the Imageobject still exists, but is invalid because it no longer contains an actual image. When you set the PictureBox.Imageproperty to a loaded Imageobject, the PictureBoxcontrol assumes that the Imageobject will remain valid so that it can reuse it later any time the control needs to repaint itself to the screen. For instance:
您的问题很可能是,在某些时候,您正在调用Dispose其中一个Image对象的方法。当您调用 时Image.Dispose,它会从内存中删除底层图像数据,因此该Image对象仍然存在,但由于不再包含实际图像而无效。当您将PictureBox.Image属性设置为加载的Image对象时,PictureBox控件假定该Image对象将保持有效,以便以后在控件需要将自身重新绘制到屏幕上时可以重用它。例如:
Dim myImage As Image = Image.FromFile("file path")
PictureBox1.Image = myImage
PictureBox1.Refresh() ' This works
myImage.Dispose()
PictureBox1.Refresh() ' This throws an exception because it tries to access the disposed Image object
The PictureBoxcontrol will automatically dispose of the image for you when it is disposed, so you don't need to worry about disposing it yourself. The only time you should be disposing your images is when you are not giving them to any other objects for later use.
该PictureBox控件将自动配置为你的形象,当它被设置,所以你不必担心自己处置它。您应该处理图像的唯一时间是您不将它们提供给任何其他对象以供以后使用。
回答by Vikrant Takkar
Here is my solution, somebody could use it, even though the question is old.
这是我的解决方案,有人可以使用它,即使问题很老。
Dim myImage As Image = Image.FromFile("file path")
PictureBox1.Image = myImage.clone // Use clone to give a new copy not a reference of image
PictureBox1.Refresh() // This works
myImage.Dispose()
PictureBox1.Refresh() // This works also because we've a copy not reference
回答by Andrei
PictureBox1.Image = myImage.Clone This way you are using a copy of the image so it does not matter what happens with the original
PictureBox1.Image = myImage.Clone 这样您就使用了图像的副本,因此原始图像发生了什么无关紧要

