Using a VB.NET variable between different forms - vb.net

I am trying to use the VB.NET program settings to load a background image for every form every time the form is loaded. So far I've managed to get the program to set the background in one form, and that changes the background for every other form. However, when each form is closed and re-opened while the program is running, the background changes back to the default one. I need to somehow change the background once and load it every time the form is opened, so that it doesn't switch back every time the form is re-opened while the program is running. I think there is some way to do this using the My.Settings in VB.NET, but I'm not sure.
This is the code that changes the background for each form:
Me.BackgroundImage = PreviewBackgroundBox.Image
MainForm.BackgroundImage = PreviewBackgroundBox.Image
LogInForm.BackgroundImage = PreviewBackgroundBox.Image
The PreviewBackgroundBox is used to show the user the image before they apply it, and then when they click apply then the image is taken from the PreviewBackgroundBox and set as the background for all the forms.
Could someone help me with this?
Thanks!

Basically you need a dictionary remembering the image is to be displayed for each form. You could store such a dictionary in a module together with methods to handle the logic involved
Private imageDict As New Dictionary(Of String, Image)
Public Sub SetImage(ByVal formName As String, ByVal img As Image)
imageDict(formName) = img
End Sub
Public Function GetImage(ByVal formName As String) As Image
Dim img As Image
If imageDict.TryGetValue(formName, img) Then
Return img
End If
Return Nothing 'Or return a default image
End Function
Note: Dictionaries store some data and associate it with a key that is used to retrieve this data. Here I would use the form's name as Key. You could also use the form's type GetType(Form1) or Me.GetType() and use a Dictionary(Of Type, Image) instead.
Whenever the user selects another image call SetImage in order to remember it. When a form is opened call GetImage to get the remembered image.

Related

VB.Net If statement to check if a specific image from my resources is loaded

I want to use an If statment to check if a specific image from my resources is loaded.
I want to change the image when it is clicked as in:
If PictureBox1.Image = My.Resources.BIKE13 Then
PictureBox1.Image = My.Resources.BIKE13_Helmet
End If
I'm going to use several ElseIf Statements
After some search I found several ways to do it but I have about 20-30 images and I'm and I need a simple method.
(VS 2010)
That code cannot possibly work for two reasons. Firstly, an Image is a reference type object, so to compare like that you would have to use the Is operator rather than =. Secondly, My.Resources creates a new object each time, so even using Is will never give you a match.
What you need to do is use the My.Resources property once and once only and assign the Image object to a member variable. You can then use Is with that field.
E.g.
Private bike13Image As Image = My.Resources.BIKE13
Private bike13HelmetImage As Image = My.Resources.BIKE13_Helmet
and
If PictureBox1.Image Is bike13Image Then
PictureBox1.Image = bike13HelmetImage
End If

Array of images VB.NET

I am new to VB.NET. I am developing a game in which the user has to guess the name of the image that appears in a picturebox. The user has to enter the answer in a textbox. If it is right, a button appears and changes the image of the picturebox.
I would like the image of the picturebox to change when the next level button is clicked. I want to make an array which will contain all the images with a string as the answer.
How would I go about changing the image to the next in the array after each next level button click?
Thanks
To Load images to array
Dim imgPictures(8) As Image
imgPictures(0) = Bitmap.FromFile("Filename")
To display images.
Dim i as integer = 0
Next Image
myPictureBox.Image = imgPictures(i++)
Previous Image
myPictureBox.Image = imgPictures(i--)
Make sure you are checking for maximum and minimum array values, otherwise you will get indexoutofrange exceptions.
It's hard to tell exactly what parts of the code you need help with, so I'm guessing here. I went in a different direction than #Anuraj, which hopefully is helpful.
Let's say you create an object-based array:
Dim arr(10) As Object
You then create a Sub in your code that will handle the "next level" button's click event:
Private Sub NextLevelButton(ByVal sender As Object, ByVal e As RoutedEventArgs)
'Do Stuff
End Sub
Now replace 'Do Stuff with code that retrieves the next item in the array, and then changes the image in the UI. Obviously, to do this, you'll need to know which item in the array was most recently used. The easiest way to do this is to create a global variable (outside of all subs in your code) which you will replace each time you add a new image to the UI. The value of this global variable will be the index number of the most recently used image in your array. Then, you just increment by one and grab the next image.

ImageTools only creates PNG successfully under certain conditions

I'm trying to generate images using ImageTools, and my code works and successfully creates images...but only if I have user input before trying to create the images!
If I try to generate the images in the New sub, for example, the images are created, but they only contain the textbox control from my canvas and not the image (my control consists of text + image). So the image is being created...but it's only rendering partial content.
If I put a button on my page and generate my images from the button click even handler the images are generated correctly.
So what am I doing wrong here? And how can I get my images to generate without user input (i.e. when the app launches).
I get the exact same results using WriteableBitmap in place of ImageTools, FWIW.
I create stackpanels with a canvas and my text/image elements, then use the standard code to render the images to files in isolated storage. Since it all works perfectly after user input I don't know which parts of the code to provide...I'm basically using unmodified sample code.
Code parts (this is all in my MainPage.XAML.VB):
Public Sub New()
InitializeComponent()
' some code commented out while debugging - not relevant here
SetupHubTiles() ' this is the method that sets up the images (see below)
End Sub
The SetupHubTiles method makes several calls to the following method:
Public Sub CreateHubTile(background As StackPanel, tileImage As String, tiletoupdate As HubTile)
Dim isoStoreTileImage = String.Format("isostore:{0}", tileImage)
'Create a bitmapImage to IsolatedStorage.
Using store As IsolatedStorageFile = IsolatedStorageFile.GetUserStoreForApplication()
'Tile image's Height * Width are 173 * 173.
Dim bitmap = New WriteableBitmap(173, 173)
'Render a bitmap from StackPanel.
bitmap.Render(background, New TranslateTransform())
Dim stream = store.CreateFile(tileImage)
bitmap.Invalidate()
bitmap.SaveJpeg(stream, 173, 173, 0, 100)
stream.Close()
End Using
SetHubTileImage(tileImage, tiletoupdate) ' this is what sets a control on the MainPage to display the generated image
End Sub
And finally the button click handler (which I just implemented because the code I'm using works fine in another app, but that app always gets user input before creating images, so I figured it was the only difference between the two apps)
Private Sub StartButton_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles StartButton.Click
SetupHubTiles()
End Sub
As you can see the code being executed is identical, but I get a different result when I run it directly in my contructor compared to running it from a button click handler.
The goal is for these images to be generated at runtime (without any interaction from the user) to be used in the UI.
I've tried a few different methods of doing this, but I always get the same results - an image is generated with just text when there should be text + image. I am using the same method in other apps with the only difference being those other apps are not creating the images as soon as the app launches, which may be the problem.
It also doesn't seem to make a difference if I change the location/type of controls that I am using to build my images.
Based on your comment, try to invoke your method either later in the loading sequence or use:
Dispatcher.BeginInvoke(() => { GenerateImages(); });
This will queue the function up to be run on the next UI thread tick which should be after any pending layout work which is queued up.
The fact that you are calling this function right at the end of the constructor has no consequence (other than the fact that the variables representing different objects have been initialized). It's all happening in the same UI thread tick, before Layout is kicked off so there is nothing in the StackPanel for you to capture.
To fix this, add your code to the Loaded event of the Page and still wrap it in a Dispatcher.BeginInvoke call so that it is guaranteed to happen after all of your Controls have rendered (at least their first pass, not withstanding any content that is loaded after the startup sequence).

How do I print just one or two controls instead of the whole form in Visual Basic

I have a program that gives the user driving directions, I would like the user to be able to print just the directions or just the directions and a map by selecting a corresponding radio button for each option. How can I print just these sections and not the whole form? And how can I use the radio buttons to tell it what to print? Thanks
Updated code:
Private Sub btnprint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnprint.Click
If rbprintall.Checked = True Then
'Ad code to print all here
ElseIf rbprintdirections.Checked = True Then
lbldirections.DrawToBitmap()
lbldirections2.DrawToBitmap()
lbldirections3.DrawToBitmap()
lbldirections4.DrawToBitmap()
Else
MessageBox.Show("You must select one of the above options!")
End If
If you're using Windows Forms, almost all of the built-in controls can be easily rendered to an image using their DrawToBitmap method. If you simply want to print whatever is currently displayed by a control, this is the easiest way to do it. Do note, however, that there are a couple of caveats to what can be drawn this way. See the linked documentation for details.
Printing in the .NET Framework is also made relatively simple by taking advantage of the functionality provided in the System.Drawing.Printing namespace. If you aren't already experienced with this, Google for some tutorials. For example, there's a pretty good article here from the MSDN Magazine.
So, to accomplish your ultimate goal, you'll need to do the following:
When the user clicks "Print", determine which radio button is currently selected.
Create a temporary bitmap and grab a copy of the appropriate control in that bitmap using the control's DrawToBitmap method. (If you need to print multiple controls, create a separate temporary bitmap for each of them, and then print each of them in the next step.)
Draw that image to the printer using the Graphics.DrawImage method in the PrintPage event handler method for a PrintDocument object you've created.
EDIT: I'm not really sure where your question is with regards to the code that you've posted, but I see two primary problems.
In the first block of your if statement, the comment suggests you don't know how to print all of the controls. You have a couple of different options. If you just want to print every control on the form as it appears, you can simply use the DrawToBitmap method of the Form itself. That will create a bitmap of the form's entire client area, including all of the controls it contains.
If there are still some controls on the form that you don't want to print, even when the user chooses "Print All", you'll need to call the DrawToBitmap methods on each individual control. You might set up a loop so that you don't have to write a line of code for every control, but there's not really another good option.
I suspect you're going to have problems with the second elseif block working as you expect it to, also. Recall that I said above you need to create temporary bitmap images, and then draw into those bitmaps? The DrawToBitmap method takes two parameters:
bitmap: a System.Drawing.Bitmap that you want an image of the control to be drawn into
targetBounds: a System.Drawing.Rectangle that describes the bounds of the control that will be rendered
The code you've shown is missing both of those parameters. In this case, the second (targetBounds) is simple—because you want to draw the entire control, all you need to do is specify it's ClientRectangle property for that parameter.
For the first (bitmap) parameter, you need to do as I mentioned above and create a new Bitmap image by declaring a temporary variable. Then, you need to call the DrawToBitmap method with this temporary bitmap specified.
Maybe I can be clearer with an example. Modify your above code to look like this:
'Declare some class-level variables to hold images of the controls to print
Private bmpDirections1 As System.Drawing.Bitmap
Private bmpDirections2 As System.Drawing.Bitmap
Private bmpDirections3 As System.Drawing.Bitmap
Private bmpDirections4 As System.Drawing.Bitmap
Private Sub btnprint_Click(ByVal sender As Object, ByVal e As EventArgs) Handles btnprint.Click
If rbprintall.Checked = True Then
'Add code to print all here
ElseIf rbprintdirections.Checked = True Then
'Draw lbldirections control to bitmap variable named bmpDirections1
bmpDirections1 = New Bitmap(lbldirections.Width, lbldirections.Height)
lbldirections.DrawToBitmap(bmpDirections1, lbldirections.ClientRectangle)
'Draw lbldirections2 control to bitmap variable named bmpDirections2
bmpDirections2 = New Bitmap(lbldirections2.Width, lbldirections2.Height)
lbldirections2.DrawToBitmap(bmpDirections2, lbldirections2.ClientRectangle)
'Draw lbldirections3 control to bitmap variable named bmpDirections3
bmpDirections3 = New Bitmap(lbldirections3.Width, lbldirections3.Height)
lbldirections3.DrawToBitmap(bmpDirections3, lbldirections3.ClientRectangle)
'Draw lbldirections4 control to bitmap variable named bmpDirections4
bmpDirections4 = New Bitmap(lbldirections4.Width, lbldirections4.Height)
lbldirections4.DrawToBitmap(bmpDirections4, lbldirections4.ClientRectangle)
Else
MessageBox.Show("You must select one of the above options!")
End If
End Sub
The only thing to remember is that you need to call the Dispose method on each bitmap variable when you are finished using it. The Dispose method "releases the resources owned by the image", which means that it frees up the memory it was using. There's no reason to keep those large-ish images around if you're not going to use them again. So, you should probably do this after the print job is completed. Once you dispose the bitmap object, you will no longer be able to use the image it contained, but you can always create a new bitmap object and assign it to the variable (as shown in the above code) the next time the user clicks print.
Unrelated: There's no reason to test for If x = True. The simpler If x is the same thing, and considered by most programmers to be better style. Effectively, you're doing a double comparison against True, which isn't necessary.

Taking information from one window and putting it into another

I am developing a game and I want an options window to be used so that the user enters data into this and it carries to the main window instead of being lost...
I tried it with my recent program , guess the color , but it did not work the way I thought. I thought that I could assign it to a string in a textbox to a variable and it would carry into the main window...
I want this to happen:
The user begins the program by clicking shortcut
User clicks options in the toolbar
A new window comes onto the screen
In this window the user will select a map size then click ok the verify , radiobuttons used in this example...
Back to the main screen after clicking ok
User clicks new on toolbar to begin game
Game is then playing...
Edit:
Form1 <<< Form 2
game screen 3x3 button
end turn
Form 1
New game is begun
form 2 appears
3x3 button is pressed*
variable is used to change map (there is only one map for now)*
form2 closes and form1 shows
End turn is clicked
Generally, what you have to do is when you create a new form/window, you hold onto the reference of that form window until it closes.
Then, when it closes, you can copy the information back from the form/window that just closed into your main window (or whatever else you wish).
The key here is to expose properties on the child window which represent the inputs. So if the child window that was opened has a color that was selected, create a property which exposes that color so that the parent window can access it on the child.
EDIT: Why did I think this was a VB6 question? Did this get re-tagged? If the OP can clarify which version of VB, I'll update my example.
OOP even applies to VB6. Create an class to hold the shared data. At the application startup, create the object as a global object (variable). I hate global variables as much as the next guy, but in the case where this data needs to be seen by the whole application (a logged-in user object or a logging object, for example), it's appropriate. You can assign the values to the class object in the first form, and then read them from the class object in the second or any other form.
Example class:
Option Explicit
Private m_firstName As String
Private m_lastName As String
Public Property Get FirstName() As String
FirstName = m_firstName
End Property
Public Property Let FirstName(ByVal value As String)
m_firstName = value
End Property
Public Property Get LastName() As String
LastName = m_lastName
End Property
Public Property Let LastName(ByVal value As String)
m_lastName = value
End Property
Public Function FullName() As String
FullName = m_firstName & " " & m_lastName
End Function
I don't have VB6 on this machine, or I could have given you a better example. I think in .NET these days ;)
This may explain things quite a bit more - http://www.vbforums.com/showthread.php?t=374132