-
Dec 14th, 2016, 08:38 PM
#1
Thread Starter
PowerPoster
[RESOLVED] Adding an image to my picturebox throws an error
Hi,
I have a problem with this code.
The code as printed here works perfectly well, but as you can see, line 35 is 'Dimmed out' when I restore this line I get an 'Invalid parameter' error at line 39.
This doesn't happen at the same place in the loop every time, but it's usually Row 9 and somewhere between Column 20 to 50.
There are 8 images, and they're all visible in their respective picturebox up to this point... So they've been added correctly about 70 times each when the error occurs.
VB.NET Code:
Public Class Form1
Dim Sqr As Int32, Img() As String
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Img = {"HM_Compass_N", "HM_Compass_NE", "HM_Compass_E", "HM_Compass_SE",
"HM_Compass_S", "HM_Compass_SW", "HM_Compass_W", "HM_Compass_NW"}
Me.WindowState = 2
Grid()
End Sub
Private Sub Grid()
Dim No As Int32, BoxName As String
' Make Box0101 to Box0160, then Box0201 to box 0260... etc.
No = 0
Sqr = 17
For Ro = 1 To 40
For Co = 1 To 60
BoxName = "Box" & Ro.ToString("00")
BoxName += Co.ToString("00")
Dim Box As New PictureBox
With Box
.Name = BoxName
.BackColor = Color.Cyan
.Width = Sqr
.Height = Sqr
.Dock = DockStyle.None
.BorderStyle = BorderStyle.Fixed3D
.Padding = New System.Windows.Forms.Padding(0)
.Margin = New System.Windows.Forms.Padding(0)
.BorderStyle = BorderStyle.None
.SizeMode = PictureBoxSizeMode.StretchImage
.Visible = True
'.Image = DirectCast(My.Resources.ResourceManager.GetObject(Img(No)), Image)
End With
No += 1
If No > 7 Then No = 0
TableLayoutPanel1.Controls.Add(Box, Co, Ro) ' Col, Row
TableLayoutPanel1.SetRowSpan(Box, 1)
TableLayoutPanel1.SetColumnSpan(Box, 1)
Box.Refresh()
' This is where the magic happens, all picture boxes identified in 1 of 3 Subs.
AddHandler Box.Click, AddressOf SquareClick ' Any box Clicked.
AddHandler Box.MouseEnter, AddressOf SquareEnter ' Every box when 'Entered'.
AddHandler Box.MouseLeave, AddressOf SquareLeave ' Every box when 'Exited'.
If Ro = 1 And Co = 1 Then
Box.Dock = DockStyle.Fill
Sqr = Box.Height
Box.Dock = DockStyle.None
Box.Width = Sqr
Box.Height = Sqr
TableLayoutPanel1.Width = Sqr * 62
End If
Next
Next
Me.Show()
Button1.Text = TableLayoutPanel1.Width.ToString & "x"
Button1.Text += TableLayoutPanel1.Height.ToString
Me.Refresh()
End Sub
Private Sub SquareClick()
End Sub
Private Sub SquareEnter(sender As Object, e As System.EventArgs)
Label1.Text = sender.Name.ToString
End Sub
Private Sub SquareLeave(sender As Object, e As System.EventArgs)
Label1.Text = ""
End Sub
Private Sub Button1_Click() Handles Button1.Click
Me.Close()
End Sub
End Class
System.ArgumentException was unhandled
HResult=-2147024809
Message=Parameter is not valid.
Source=System.Drawing
StackTrace:
at System.Drawing.Image.get_FrameDimensionsList()
at System.Drawing.ImageAnimator.CanAnimate(Image image)
at System.Drawing.ImageAnimator.ImageInfo..ctor(Image image)
at System.Drawing.ImageAnimator.Animate(Image image, EventHandler onFrameChangedHandler)
at System.Windows.Forms.PictureBox.Animate(Boolean animate)
at System.Windows.Forms.PictureBox.Animate()
at System.Windows.Forms.PictureBox.OnParentChanged(EventArgs e)
at System.Windows.Forms.Control.AssignParent(Control value)
at System.Windows.Forms.Control.ControlCollection.Add(Control value)
at System.Windows.Forms.TableLayoutControlCollection.Add(Control control, Int32 column, Int32 row)
at TLP_Test3.Form1.Grid() in C:\Users\georg\documents\visual studio 2015\Projects\TLP Test3\TLP Test3\Form1.vb:line 40
at TLP_Test3.Form1.Form1_Load(Object sender, EventArgs e) in C:\Users\georg\documents\visual studio 2015\Projects\TLP Test3\TLP Test3\Form1.vb:line 10
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.Form.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)
InnerException:
What's going wrong ?
Poppa.
VS2015
Windows 10.
Last edited by Poppa Mintin; Dec 14th, 2016 at 08:48 PM.
Reason: Typo
Along with the sunshine there has to be a little rain sometime.
-
Dec 14th, 2016, 09:07 PM
#2
Re: Adding an image to my picturebox throws an error
What type of images? The call stack seems to suggest there's some issue with animating the image. If you load the images from files instead of resources, do you see the same issue?
-
Dec 15th, 2016, 08:42 AM
#3
Thread Starter
PowerPoster
Re: Adding an image to my picturebox throws an error
Originally Posted by jmcilhinney
What type of images? The call stack seems to suggest there's some issue with animating the image. If you load the images from files instead of resources, do you see the same issue?
Ok... I've changed things a bit, but first.
The original images are all .png files. No animations. But the files are .png because there are areas of transparency, if that's relevant.
I tried adding 'Me.Refresh' between the two 'Next' commands to try giving the images time to settle down. Moved the error on a few Rows
I've tried loading the files from a folder instead and although it takes much longer it still doesn't get past Ro 21.
Now, I make the grid, then add the images in a separate subroutine after that. At the same time I've loaded in a whole bunch of new image files, these are all .jpg files. These are in addition to the original files but the original files haven't been used as yet.
I've changed the picturebox names to be continuous from 'Box1' through to 'Box2400', makes life easier !
I've added a function to select different images for the different areas of the 'Map' these are not yet complete but fairly substantial.
The program ran through making the grid without a problem, but gave the same problem on the very last Ro... So, I made TPL1 invisible before starting making the grid and don't make it visible again until after making the 'Map'. Now I get the problem at ' TableLayoutPanel1.Visible = True ' in the Form1_Load.
I checked and know for certain that the last cell, Ro 40, Co 60 (Box2400) has been called, but can't be sure it's image is loaded, except that Private Sub Map() must've exited correctly else the error would occur there (I think).
Code:
Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
Img = {"HM_Compass_N", "HM_Compass_NE", "HM_Compass_E", "HM_Compass_SE",
"HM_Compass_S", "HM_Compass_SW", "HM_Compass_W", "HM_Compass_NW"}
Me.WindowState = 2
TableLayoutPanel1.Visible = False
Grid()
Map()
TableLayoutPanel1.Visible = True
End Sub
Private Sub Grid()
Dim No As Int32, BoxName As String
' Make Box1 to Box2400
No = 1
Sqr = 15
For Ro = 1 To 40
For Co = 1 To 60
BoxName = "Box" & No.ToString
Dim Box As New PictureBox
With Box
.Name = BoxName
.BackColor = Color.White
.Width = Sqr
.Height = Sqr
.Dock = DockStyle.None
.BorderStyle = BorderStyle.Fixed3D
.Padding = New System.Windows.Forms.Padding(0)
.Margin = New System.Windows.Forms.Padding(0)
.BorderStyle = BorderStyle.None
.SizeMode = PictureBoxSizeMode.StretchImage
.Visible = True
End With
TableLayoutPanel1.Controls.Add(Box, Co, Ro) ' Col, Row
TableLayoutPanel1.SetRowSpan(Box, 1)
TableLayoutPanel1.SetColumnSpan(Box, 1)
' This is where the magic happens, all picture boxes identified in 1 of 3 Subs.
AddHandler Box.Click, AddressOf SquareClick ' Any box Clicked.
AddHandler Box.MouseEnter, AddressOf SquareEnter ' Every box when 'Entered'.
AddHandler Box.MouseLeave, AddressOf SquareLeave ' Every box when 'Exited'.
If No = 1 Then
Box.Dock = DockStyle.Fill ' I want the picture cells to be square so, the TLP rows...
Sqr = Box.Height ' ...are set to 'Percent' to get the best height for the...
Box.Dock = DockStyle.None ' ...cells, but the Columns are set to 'AutoSize'. Just....
Box.Width = Sqr ' ...for the first box, I read the cell height, and make...
Box.Height = Sqr ' ...all the cells the same width. Job done!
Box.BackColor = Color.White
TableLayoutPanel1.Width = Sqr * 62
End If
No += 1
Next
Next
Button1.Text = TableLayoutPanel1.Width.ToString & "x"
Button1.Text += TableLayoutPanel1.Height.ToString
End Sub
Private Sub Map()
Dim z As String, Pic As PictureBox
z = ""
For i = 1 To 2400
z = "Box" & i.ToString
Pic = CType(TableLayoutPanel1.Controls(z), PictureBox)
Pic.Image = DirectCast(My.Resources.ResourceManager.GetObject(Feature(i)), Image)
Next
End Sub
Private Function Feature(ByVal ThisBox As Int32) As String
Dim Pic As String
Select Case ThisBox
Case 1 To 11, 13 To 17, 26 To 31, 33 To 43, 47 To 58, 60, 61 To 71, 75,
88, 93 To 102, 108 To 118, 121, 122, 177, 181, 239, 240, 601, 721, 722, 723,
781, 782, 783, 841, 842, 900, 901, 902, 959, 960, 1080, 1081,
1139 To 1142, 1200, 1261, 1262, 1321, 1439 To 1440, 1500, 1740, 1799,
1800, 1859, 1860, 2161, 2219 To 2222, 2279 To 2281, 2284 To 2285,
2296 To 2304, 2307, 2324 To 2330, 2340, 2343 To 2346, 2355 To 2364,
2366 To 2369, 2383 To 2391
Pic = "Grass"
Case 1216, 1218, 1396, 1398
Pic = "NS62"
Case 1217, 1275 To 1279, 1335 To 1339, 1397
Pic = "Grass"
Case 562, 638, 680, 698, 740, 817, 864, 875, 930, 932
Pic = "NS62"
Case 563 To 577, 621 To 637, 681 To 697, 741 To 757,
801 To 816, 865 To 874, 931
Pic = "Grass"
Case 1302 To 1306, 1356 To 1368, 1415 To 1429, 1475 To 1491,
1536 To 1550, 1596 To 1608, 1656 To 1668, 1718 To 1728,
1777 To 1787
Pic = "Grass"
Case 532, 672, 1007, 1893
Pic = "NS64"
Case 12, 32, 661, 1020, 2365, 2400
Pic = "NS61"
Case Else
Pic = "NS60"
End Select
Return Pic
End Function
System.ArgumentException was unhandled
HResult=-2147024809
Message=Parameter is not valid.
Source=System.Drawing
StackTrace:
at System.Drawing.Image.get_FrameDimensionsList()
at System.Drawing.ImageAnimator.CanAnimate(Image image)
at System.Drawing.ImageAnimator.ImageInfo..ctor(Image image)
at System.Drawing.ImageAnimator.Animate(Image image, EventHandler onFrameChangedHandler)
at System.Windows.Forms.PictureBox.Animate(Boolean animate)
at System.Windows.Forms.PictureBox.Animate()
at System.Windows.Forms.PictureBox.OnVisibleChanged(EventArgs e)
at System.Windows.Forms.Control.OnParentVisibleChanged(EventArgs e)
at System.Windows.Forms.Control.OnVisibleChanged(EventArgs e)
at System.Windows.Forms.ScrollableControl.OnVisibleChanged(EventArgs e)
at System.Windows.Forms.Control.SetVisibleCore(Boolean value)
at System.Windows.Forms.Control.set_Visible(Boolean value)
at Pirates_V5.Form1.Form1_Load(Object sender, EventArgs e)
at System.EventHandler.Invoke(Object sender, EventArgs e)
at System.Windows.Forms.Form.OnLoad(EventArgs e)
at System.Windows.Forms.Form.OnCreateControl()
at System.Windows.Forms.Control.CreateControl(Boolean fIgnoreVisible)
at System.Windows.Forms.Control.CreateControl()
at System.Windows.Forms.Control.WmShowWindow(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ScrollableControl.WndProc(Message& m)
at System.Windows.Forms.Form.WmShowWindow(Message& m)
at System.Windows.Forms.Form.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)
InnerException:
Poppa.
VS2015
Windows 10
i7 Processor machine.
8Gb RAM.
Along with the sunshine there has to be a little rain sometime.
-
Dec 15th, 2016, 12:16 PM
#4
Thread Starter
PowerPoster
Re: Adding an image to my picturebox throws an error
Been working with this for a while now and it's looking as though it's a memory problem... well I guess 2400 is a lot of PictureBoxes.
I get a recommendation to 'Reserve Memory' for them, but can't find how to do that.
I tried declaring a PictureBox array... Dim PicBox(2401) As PictureBox
But then I couldn't find how to add them to the TLP, nor how to set their parameters.
I'm just getting further and further bogged down.
Poppa.
Along with the sunshine there has to be a little rain sometime.
-
Dec 15th, 2016, 12:29 PM
#5
Re: Adding an image to my picturebox throws an error
You will get that error is the particular image has been Disposed. I'm not saying that is that cause of your problem, but it is at least one way to reproduce that particular error.
A general observation is that you are putting more pressure on the system than appears to be warranted.
From your Feature method, you need only five images:
- Grass
- NS62
- NS64
- NS61
- NS60
Yet in the Map method, you are creating 2400 unique images. This statement:
Code:
Pic.Image = DirectCast(My.Resources.ResourceManager.GetObject(Feature(i)), Image)
creates a unique System.Image object each time it is executed.
If you create a Dictionary of the needed images with something like this:
Code:
Private mapImages As Dictionary(Of String, Image)
Private Sub InitializeMapImages()
If mapImages Is Nothing Then
mapImages = New Dictionary(Of String, Image)
Dim imageNames As String() = {"Grass", "NS62", "NS64", "NS61", "NS60"}
For Each imageName As String In imageNames
Dim img As Image = DirectCast(My.Resources.ResourceManager.GetObject(imageName), Image)
If img Is Nothing Then
Throw New ArgumentException(imageName & " not found in Resources")
End If
mapImages.Add(imageName, img)
Next
End If
End Sub
and call InitializeMapImages in the Form_Load handler then you could change:
Code:
Pic.Image = DirectCast(My.Resources.ResourceManager.GetObject(Feature(i)), Image)
to
Code:
Pic.Image = mapImages(Feature(i))
Just a suggestion.
-
Dec 15th, 2016, 04:40 PM
#6
Hyperactive Member
Re: Adding an image to my picturebox throws an error
Yes definately do what TnTinMN advocates. 2400 images is a TON of memory!
As a general practice, if you ever plan on using an image in more than one place in your project, still add it only once (you can dim it to memory) and then reference that.
Code:
Dim MyBitmap As Bitmap
That merely creates an empty variable though. You will then need to "link" this variable to a physical bitmap somewhere on your harddrive ie "c:\TestBitmap" or whatever. A far better way would be to use the content manager in the IDE though.
There should be plenty of material on the web for how to set that up.
-
Dec 16th, 2016, 08:41 AM
#7
Thread Starter
PowerPoster
Re: Adding an image to my picturebox throws an error
Originally Posted by TnTinMN
You will get that error is the particular image has been Disposed. I'm not saying that is that cause of your problem, but it is at least one way to reproduce that particular error.
A general observation is that you are putting more pressure on the system than appears to be warranted.
From your Feature method, you need only five images:
- Grass
- NS62
- NS64
- NS61
- NS60
Yet in the Map method, you are creating 2400 unique images. This statement:
Code:
Pic.Image = DirectCast(My.Resources.ResourceManager.GetObject(Feature(i)), Image)
creates a unique System.Image object each time it is executed.
If you create a Dictionary of the needed images with something like this:
Code:
Private mapImages As Dictionary(Of String, Image)
Private Sub InitializeMapImages()
If mapImages Is Nothing Then
mapImages = New Dictionary(Of String, Image)
Dim imageNames As String() = {"Grass", "NS62", "NS64", "NS61", "NS60"}
For Each imageName As String In imageNames
Dim img As Image = DirectCast(My.Resources.ResourceManager.GetObject(imageName), Image)
If img Is Nothing Then
Throw New ArgumentException(imageName & " not found in Resources")
End If
mapImages.Add(imageName, img)
Next
End If
End Sub
and call InitializeMapImages in the Form_Load handler then you could change:
Code:
Pic.Image = DirectCast(My.Resources.ResourceManager.GetObject(Feature(i)), Image)
to
Code:
Pic.Image = mapImages(Feature(i))
Just a suggestion.
Thanks TnTinMN,
First I'll rename 'Grass' to 'NS62', then rename some of the other images, remove one altogether and produce four new ones.
Then add a bit to your suggestion, make the changes in Subroutine 'Grid', and in Function 'Feature', remove Subroutine 'Map', and try it out...
Brilliant, worked first time. It worked much faster too, an added bonus.
Code:
Private Sub InitializeMapImages()
If mapImages Is Nothing Then
mapImages = New Dictionary(Of String, Image)
Dim imageNames As String() = {"NS00", "NS01", "NS02", "NS03", "NS04", "NS05", "NS06", "NS07",
"NS08", "NS09", "NS10", "NS11", "NS12", "NS13", "NS14", "NS15", "NS16", "NS17", "NS18",
"NS19", "NS20", "NS21", "NS22", "NS23", "NS24", "NS25", "NS26", "NS27", "NS28", "NS29",
"NS30", "NS31", "NS32", "NS33", "NS34", "NS35", "NS36", "NS37", "NS38", "NS39", "NS40",
"NS41", "NS42", "NS43", "NS44", "NS45", "NS46", "NS47", "NS48", "NS49", "NS50", "NS51",
"NS52", "NS53", "NS54", "NS55", "NS56", "NS57", "NS58", "NS59", "NS60", "NS61", "NS62",
"HM_Compass_N", "HM_Compass_NE", "HM_Compass_E", "HM_Compass_SE",
"HM_Compass_S", "HM_Compass_SW", "HM_Compass_W", "HM_Compass_NW"}
For Each imageName As String In imageNames
Dim img As Image = DirectCast(My.Resources.ResourceManager.GetObject(imageName), Image)
If img Is Nothing Then
Throw New ArgumentException(imageName & " not found in Resources")
End If
mapImages.Add(imageName, img)
Next
End If
End Sub
I tried to use a For - To loop to get all the Strings, in the end it was easier to quickly make a subroutine to print 'em all out for me !
Oh! A split infinitive... Tut Tut !
So... Now the question is not only answered, the problem is fixed too... Hopefully another lesson learned.
Thanks again guys...
Poppa.
Along with the sunshine there has to be a little rain sometime.
-
Dec 16th, 2016, 08:44 AM
#8
Thread Starter
PowerPoster
Re: Adding an image to my picturebox throws an error
Quick question to TnTinTN
What does this mean ?
You will get that error is the particular image has been Disposed
Pop.
Along with the sunshine there has to be a little rain sometime.
-
Dec 16th, 2016, 09:18 AM
#9
Re: Adding an image to my picturebox throws an error
Originally Posted by Poppa Mintin
What does this mean ?
You will get that error is the particular image has been Disposed
A simplistic explanation is that the Dispose method on the object has been called.
The Dispose method (if an object sports one) is intended to release native resources (memory/handles/etc.) allocated by the object that are the sole responsibility of the particular object. The Dispose method is also intended to call the Dispose method on any .Net objects that it owns that also have a Dispose method.
Disposable objects implement the IDisposable interface that declares the Dispose method.
The ability to call a Dispose method on an object provides a deterministic mechanism for releasing its allocated resources instead of waiting for the .Net Garbage collector to do so when it gets around to it. For heavy weight objects like images, it is a good idea to release its resources as soon as you no longer need to access the image.
For a more thorough explanation, see:
Memory Management and Garbage Collection in the .NET Framework
-
Dec 16th, 2016, 09:32 AM
#10
Thread Starter
PowerPoster
Re: Adding an image to my picturebox throws an error
Originally Posted by TnTinMN
A simplistic explanation is that the Dispose method on the object has been called.
Yeah, I (sort of) knew most of that... My question was more: 'Did you mean'
You will get that error ( if) the particular image has ( not) been Disposed.
Pop.
Last edited by Poppa Mintin; Dec 16th, 2016 at 09:39 AM.
Along with the sunshine there has to be a little rain sometime.
-
Dec 16th, 2016, 11:44 AM
#11
Re: Adding an image to my picturebox throws an error
I would assume "is" was meant to be "if" as that is a common typo.
But you would get the error if you Disposed the bitmap, and then tried to use it, which was what TnTinMN was saying.
-
Dec 16th, 2016, 11:52 AM
#12
Thread Starter
PowerPoster
Re: [RESOLVED] Adding an image to my picturebox throws an error
Ah, OK I see...
Thanks Passel
Along with the sunshine there has to be a little rain sometime.
-
Dec 16th, 2016, 12:14 PM
#13
Re: [RESOLVED] Adding an image to my picturebox throws an error
So my writing needs a a translator to fix my propensity to use the wrong word/leave words out/leave partial thoughts in/and the miscellaneous spelling/grammar mistakes...nothing new there!
Posting Permissions
- You may not post new threads
- You may not post replies
- You may not post attachments
- You may not edit your posts
-
Forum Rules
|
Click Here to Expand Forum to Full Width
|