2012-12-17 116 views
4

我有一個窗體,用戶可以先掃描到位圖。掃描完成後,位圖被加載,我有4個文本框,然後啓用。在每個文本框旁邊,我有一個名爲「從圖像剪切」的按鈕。當用戶點擊按鈕時,他們可以點擊並拖動位圖以使用MODI獲取選定的文本。PictureBox拋出「Parameter is not valid」ArgumentException當選項卡按下

除了一個令人討厭的bug之外,這個工作非常完美:當我點擊一個「從圖像剪切」按鈕並拖動一個正方形時,它可以很好地將文字信息提供給文本框。然後,如果我點擊下一個文本框,它會非常好,但如果我使用Tab鍵離開字段,我會得到一個「參數無效」ArgumentException並且它不顯示任何幫助代碼中的位置事故發生。我可以在表單中查看,沒有任何問題,但是一旦位圖被掃描,當我使用Tab鍵時,它會崩潰10次中的9次。

我試圖用這個來覆蓋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 

...但它仍然崩潰。

有什麼不對的建議嗎?由於我不知道從哪裏開始調試,我不知道要顯示哪些代碼。

EDIT 1

下面是ArgumentException堆棧跟蹤獲取引發:在System.Drawing.Image.get_Width

  • ()
  • 在System.Drawing.Image對象。 get_Size()
  • at System.Windows.Forms.PictureBox.ImageRectangleFromSizeMode(PictureBoxSizeMode mode)
  • at System.Win dows.Forms.PictureBox.OnPaint(PaintEventArgs的PE)
  • 在System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs的E,Int16類型層)
  • 在System.Windows.Forms.Control.WmPaint(消息&米)
  • 在System.Windows.Forms.Control.WndProc(消息&米)
  • 在System.Windows.Forms.Control.ControlNativeWindow.OnMessage(消息&米)
  • 在System.Windows.Forms.Control.ControlNativeWindow .WndProc(消息&米)
  • 在System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr的的HWND,MSG的Int32,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原因,的Int32 pvLoopData)
  • 在System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(的Int32原因,ApplicationContext的上下文)
  • at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason,ApplicationContext context)
  • at Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase。OnRun()
  • 在Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.DoApplicationModel()
  • 在Microsoft.VisualBasic.ApplicationServices.WindowsFormsApplicationBase.Run(字符串[] COMMANDLINE)
  • 在ORC_Testing.My.MyApplication.Main(字符串[]參數)在17d14f5c-a337-4978-8281-53493378c1071.vb:線81
  • 在System.AppDomain._nExecuteAssembly(RuntimeAssembly組件,字串[] args)
  • 在System.AppDomain.ExecuteAssembly(字符串assemblyFile,證據assemblySecurity,字串[] args)
  • 微軟。 VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
  • 在System.Threading.ThreadHelper.ThreadStart_Context(對象狀態)
  • 在System.Threading.ExecutionContext.Run(的ExecutionContext的ExecutionContext,ContextCallback回調,對象的狀態,布爾ignoreSyncCtx)
  • 在System.Threading.ExecutionContext.Run(的ExecutionContext的ExecutionContext,ContextCallback回調,對象狀態)
  • 在System.Threading.ThreadHelper.ThreadStart()

編輯2

這裏是我是如何掃描/加載圖像:

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. 
+0

你有沒有從異常調用堆棧?你知道代碼中的哪一行失敗嗎?你能展示代碼的那一部分嗎? –

+0

是的,但因爲我不是很喜歡我VS不知道從哪裏真正開始。消息:「參數無效」。來源:「System.Drawing」。你想要「StackTrace」? – gubbfett

+0

哦,不。我無法真正看到代碼失敗的地方。 – gubbfett

回答

9

你的問題可能是,在某些時候,你在呼喚你的Image對象之一的Dispose方法。當你調用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 

它被設置時,PictureBox控制將自動爲您處理的圖像,所以您不必擔心自己處置它。你應該設置你的圖像的唯一情況是,當你不給他們以供以後使用的任何其他對象。

+0

非常感謝!很好的解釋! – gubbfett

+0

仍然有趣的是,它使用鼠標來完成所有這些工作,並創建和處理實例,然後當我在帶有選項卡的字段之間移動時,它崩潰了。但現在它們都起作用了。 :) – gubbfett

+1

是的,這有點奇怪,但並不完全出乎意料。在使用鍵盤時,無論出於何種原因,Windows都認爲您的PictureBox需要重新粉刷,但使用鼠標時,它不會。我確信這有一個很好的理由。使用鼠標和鍵盤時,傳遞的窗口消息是不同的。然而,最終,這並不重要,因爲遲早會需要重新繪製其他原因,例如窗口被調整大小等等。 –

0

PictureBox1.Image = myImage.Clone 您使用的是圖像的副本,以便沒關係與原

1

這裏發生了什麼這種方式是我的解決方案,有人可能會使用它,即使問題老了。

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 
相關問題