如何解决此问题:参数无效 [英] How to solve this problem : Parameter is not valid
问题描述
大家好.
首先,对不起我的英语不好.
使用:
Visual Studio 2005
Visual Basic.NET
我正在开发一个小型Media Player,该应用程序可以播放最流行的音乐格式,并可以查看某些图像格式.
我有继承自System.Windows.Forms.Control
的自定义控件(称为BtnEx)
我想解决下一个问题:
ArgumentException:参数无效
此错误发生在我的代码的下一行:
Hello everyone.
First of all, sorry for my bad english.
Using:
Visual Studio 2005
Visual Basic.NET
I''m developing a small Media Player, an application which can play most popular music formats, and can view some image formats.
I have my custom control (called BtnEx) that inherits System.Windows.Forms.Control
I want to solve the next problem:
ArgumentException : Parameter is not valid
This error occurs in the next line of my code:
Dim CImg as New Bitmap (PImg, e.ClipRectangle.Width - 2, e.ClipRectangle.Height - 2)
但是仅在设计模式下,而不是在我运行程序时(通过按F5按钮).
当我构建项目时,一切正常,直到按我的自定义控件为止(用于拖动和选择).这一切都是在设计模式(IDE)中发生的
一个"X"图像而不是控件的图像出现,并且Visual Studio显示带有错误描述的MessageBox.在该说明中,我可以读取发生错误的代码行. (ArgumentException发生在文件"C:\ ... \ BtnEx.vb"行:67中.
当我再次构建项目时,红色的"X"图像消失了,一切都很好,但是正如我所说,当我单击控件时,就会发生异常.
我在 OnPaint 子程序中调用此过程.
这是OnPaint子目录:
But only in Design Mode, not when I run my program (by pressing the F5 button).
When i build my project all works fine until I press my custom control (For dragging and selecting). Thats all happening in Design Mode (IDE)
A "X" image is appearing instead of Control''s Image, and Visual Studio shows MessageBox with error description. In that description I can read in which line of code error occurs. (ArgumentException occured in file "C:\ ... \BtnEx.vb" line: 67.
When I Build my project (again) the red "X" image dissapears and all loks fine, but as I said, when i click on control that exception occurs.
I''m calling this procedure in OnPaint Sub.
This is the OnPaint Sub:
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
If PImg Is Nothing = False Then
' Error is in the next line:
Dim CImg As New Bitmap(PImg, e.ClipRectangle.Width - 2, e.ClipRectangle.Height - 2)
' When I run this program (F5) then no error is occured.
If Me.Enabled = True Then
Select Case MS
Case EMouseState.MouseHover
' HighLight The Image
IMGA.SetGamma(0.57#)
e.Graphics.DrawImage(CImg, CRect, 0, 0, CRect.Width, CRect.Height, GraphicsUnit.Pixel, IMGA)
Case EMouseState.MouseDown
' Make Image darker
IMGA.SetGamma(1.77#)
e.Graphics.DrawImage(CImg, CRect, 0, 0, CRect.Width, CRect.Height, GraphicsUnit.Pixel, IMGA)
Case EMouseState.MouseUp
If InB = True Then ' If mouse is on it.
IMGA.SetGamma(0.57#)
e.Graphics.DrawImage(CImg, CRect, 0, 0, CRect.Width, CRect.Height, GraphicsUnit.Pixel, IMGA)
Else
e.Graphics.DrawImage(CImg, CRect)
End If
Case EMouseState.MouseLeave
e.Graphics.DrawImage(CImg, CRect)
End Select
Else
' Method used by MicroSoft to paint controls disabled.
ControlPaint.DrawImageDisabled(e.Graphics, CImg, 1, 1, Color.Transparent)
End If
End If
End Sub
当我使用数字代替e.ClipRectangle.Width或e.ClipRectangle.Height时,它运行良好.
例子:
When I use numbers instead e.ClipRectangle.Width or e.ClipRectangle.Height it runs fine.
Example :
Dim InitWidth As Integer = 42
Dim InitHeight As Integer = 42
Dim CImg As New Bitmap (PImg, InitWidth, InitHeight)
' OR:
Dim CImg As New Bitmap (PImg, 42, 42)
' Then runs very well, without errors. Why ??
我已经使用MsgBox测试了e.ClipRectangle.Width:
I have tested e.ClipRectangle.Width with MsgBox:
MsgBox (e.ClipRectangle.Width.Tostring)
'And MsgBox shows a correct value: 42
我知道我可以通过其他方式执行此操作,但是我想知道为什么会发生这种情况?
其他方法之一是使用控件的 Me.Width 和 Me.Height 属性,但是当我只想使用控件的一部分来绘画时会怎样呢?
使用有效的Me.Width和Me.Height属性的示例.
I know I can do this in other ways, but I want to know why is that happening ?
One of the other ways is to use Me.Width and Me.Height properties of control, but what when i want to use only part of control to draw on it ??
Example using Me.Width and Me.Height properties that works.
Dim CImg As New Bitmap (PImg, Me.Width - 2, Me.Height - 2)
这是整个班级
This is the whole Class
Public Class BtnEx
Inherits Control
Private PImg As Image = Nothing
Public Property Image() As Image
Get
Return PImg
End Get
Set(ByVal Value As Image)
PImg = Value
Me.Refresh()
End Set
End Property
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
MyBase.OnPaint(e)
If PImg Is Nothing = False Then
Dim CRect As New Rectangle(1, 1, e.ClipRectangle.Width - 2, e.ClipRectangle.Height - 2)
' MsgBox("InitW : InitH = " + e.ClipRectangle.Width.ToString + " : " + e.ClipRectangle.Heigh.ToString)
Dim IMGA As New Drawing.Imaging.ImageAttributes
' ERROR : Parameter is not valid >
Dim CImg As New Bitmap(PImg, e.ClipRectangle.Width - 2, e.CLipRectangle.Height - 2)
' I need to change size of the image (PImg) because user can choose an image that is bigger than by control.
If Me.Enabled = True Then
Select Case MS
Case EMouseState.MouseHover
' HighLight The Image
IMGA.SetGamma(0.57#)
e.Graphics.DrawImage(CImg, CRect, 0, 0, CRect.Width, CRect.Height, GraphicsUnit.Pixel, IMGA)
Case EMouseState.MouseDown
' Make Image darker
IMGA.SetGamma(1.77#)
e.Graphics.DrawImage(CImg, CRect, 0, 0, CRect.Width, CRect.Height, GraphicsUnit.Pixel, IMGA)
Case EMouseState.MouseUp
If InB = True Then ' If mouse is on it.
IMGA.SetGamma(0.57#)
e.Graphics.DrawImage(CImg, CRect, 0, 0, CRect.Width, CRect.Height, GraphicsUnit.Pixel, IMGA)
Else
e.Graphics.DrawImage(CImg, CRect)
End If
Case EMouseState.MouseLeave
e.Graphics.DrawImage(CImg, CRect)
End Select
Else
' Method used by MicroSoft to paint controls disabled.
ControlPaint.DrawImageDisabled(e.Graphics, CImg, 1, 1, Color.Transparent)
End If
End If
End Sub
Protected Overrides Sub InitLayout()
MyBase.InitLayout()
Me.Refresh
End Sub
'Used to Refresh Control.
Private Sub II()
Me.Refresh()
End Sub
Dim InB As Boolean
Private Enum EMouseState
MouseUp = 0
MouseHover = 1
MouseDown = 2
MouseLeave = 3
End Enum
Dim MS As EMouseState
Protected Overrides Sub OnMouseEnter(ByVal e As System.EventArgs)
InB = True
MyBase.OnMouseEnter(e)
MS = EMouseState.MouseHover
II()
End Sub
Protected Overrides Sub OnMouseLeave(ByVal e As System.EventArgs)
MyBase.OnMouseLeave(e)
InB = False
MS = EMouseState.MouseLeave
II()
End Sub
Protected Overrides Sub OnMouseDown(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseDown(e)
If e.Button = Windows.Forms.MouseButtons.Left = True Then
MS = EMouseState.MouseDown
II()
End If
End Sub
Protected Overrides Sub OnEnabledChanged(ByVal e As System.EventArgs)
MyBase.OnEnabledChanged(e)
Me.Refresh()
End Sub
Protected Overrides Sub OnMouseUp(ByVal e As System.Windows.Forms.MouseEventArgs)
MyBase.OnMouseUp(e)
MS = EMouseState.MouseUp
II()
End Sub
Public Sub New()
Me.SetStyle(ControlStyles.AllPaintingInWmPaint Or ControlStyles.OptimizedDoubleBuffer Or ControlStyles.ResizeRedraw Or ControlStyles.Selectable Or ControlStyles.SupportsTransparentBackColor Or ControlStyles.UserPaint Or ControlStyles.StandardClick, True)
Me.DoubleBuffered = True
MS = EMouseState.MouseLeave
Me.Refresh()
End Sub
End Class
最后,对于大问题深表歉意,并在此先感谢.
And on the end, sorry for big question, and Thanks in Advance.
推荐答案
请对调用的所有三个参数进行完整检查:image(应该是有效的,不能为null ),匹配正宽度和高度.由于涉及设计模式,因此在调试器中很难做到这一点.要调查这种情况,可以使用类System.Diagnostics.EventLog
,请参见 http://msdn .microsoft.com/en-us/library/system.diagnostics.eventlog.aspx [
现在,可能的分辨率.设计时可能是一场灾难,很难调试-不要过度使用它.检查属性System.ComponentModel.Component.DesignMode
的值,如果在DesignMode
为true
时执行了控制方法,请避免进行任何详尽的处理或有问题的处理.您的设计模式应仅允许使用正确的边界正确渲染控件,并允许使用PropertyGrid
编辑属性.应避免所有仅在应用程序执行模式(而非设计模式)中有用的过多事件处理.
请参阅 http://msdn.microsoft.com/en-us/library/system .componentmodel.component.designmode.aspx [ ^ ].
-SA
Please do some sanity check of all of three parameters of the call: image (should be valid, not null), matching positive width and height. This is hard to do under debugger as Design mode is involved. To investigate the situation, you can use the classSystem.Diagnostics.EventLog
, see http://msdn.microsoft.com/en-us/library/system.diagnostics.eventlog.aspx[^].
You will get all the log information in the system log where you can examine it using the "Event Log" viewer, using "Eventvwr.msc".
Now, the possible resolution. Design-time can be a disaster, very hard to debug — don''t overuse it. Check up the value of the propertySystem.ComponentModel.Component.DesignMode
and avoid any extensive or questionable processing if your control methods are executed when theDesignMode
istrue
. Your design mode should only allow to render your control correctly with correct bounds and allow for editing of the properties using thePropertyGrid
. All excessive event processing useful only in application execution mode (not design mode) should be avoided.
See http://msdn.microsoft.com/en-us/library/system.componentmodel.component.designmode.aspx[^].
—SA
@ SAKryukov -感谢您的快速回复.我很感激.
@SAKryukov - Thank you for the quick reply. I appreciate it.
请对调用的所有三个参数进行完整检查:图像(应该是有效的,不能为null),匹配正宽度和高度.
Please do some sanity check of all of three parameters of the call: image (should be valid, not null), matching positive width and height.
我已经检查了代码中的图片:
I have checked the image in the code:
If PImg Is Nothing = False
而且我还用MsgBox检查了高度和宽度:
And I have also checked Height and Width with MsgBox:
MsgBox ("Height is : " + e.ClipRectangle.Height.ToString)
' MsgBox returns the correct value : 42 in this case
但是,在您的帮助下,我当然找到了解决方案.
你给我一个主意.
我将此代码放在OnPaint Sub中.它检查程序是否处于设计模式.
But I have found a solution, of course, with your help.
You gave me an idea.
I put this code in the OnPaint Sub. It checks if the program is in Design Mode or not.
' Using Control.DesignMode
If Me.DesignMode = True Then
' Do some stuff like : Draw image without using e.ClipRectangle, or something else
Else ' Running, draw images correctly
Dim CImg As New Bitmap (PImg, e.ClipRectangle.Width - 2, e.ClipRectangle.Height - 2)
' ... ... ...
End If
而且它可以正常工作.
您使用Control.DesingMode
的想法很棒.
这使我可以从PropertyGrid
编辑属性
我为你的ansewr投了5票.非常感谢.
And it works without any error.
Your idea to using a Control.DesingMode
is great.
This allow me to edit properies from the PropertyGrid
I voted 5 for your ansewr. Thanks a lot.
这篇关于如何解决此问题:参数无效的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!