What's new

.NET [VB.net]Dynamic Controls with events

1

1_UP

Enthusiast
Messages
10
Reaction score
6
pokelauncherimage.png

This is coming from another project of mine that I never quiet finished but figured it could be used for a useful guide. In this post I am just doing buttons but you can really do the same thing for any control.This is going to be pretty lengthy because I am just taking code straight from the project and this will not work as is since you wont have the files to do so. But once I get through to explaining everything you will be able to change it to be used for whatever you want.


To start us off I made and array of strings that hold pretty much all the information that I would need for the buttons.


Code:
  Dim gen1 As String = "Resources\Roms\GenerationI\"
  Dim gen2 As String = "Resources\Roms\GenerationII\"
  Dim gen3 As String = "Resources\Roms\GenerationIII\"
  Dim gen4 As String = "Resources\Roms\GenerationIV\"
  Dim gen5 As String = "Resources\Roms\GenerationV\"
  Dim mysteryDungeon As String = "Resources\Roms\MysteryDungeon\"
  Dim ranger As String = "Resources\Roms\Ranger\"
  Dim spinoff As String = "Resources\Roms\Spinoffs\"
  Dim vbaPath As String = "Resources\Emulator\vba\VisualBoyAdvance.exe"
  Dim desumePath As String = "Resources\Emulator\DeSmuME\DeSmuME.exe"
  'Built an array that will contain all the information we need for each game
  Dim gameInfo(,) As String = New String(,) {{gen1 & "Red\Pokemonred.zip", "Pokemon Red", vbaPath},
  {gen1 & "Blue\Pokemonblue.zip", "Pokemon Blue", vbaPath},
  {gen1 & "Yellow\Pokemonyellow.zip", "Pokemon Yellow", vbaPath},
  {gen1 & "Green\Pokemongreen.zip", "Pokemon Green", vbaPath},
  {gen2 & "Gold\Pokemongold.zip", "Pokemon Gold", vbaPath},
  {gen2 & "Silver\Pokemonsilver.zip", "Pokemon Silver", vbaPath},
  {gen2 & "Crystal\Pokemoncrystal.zip", "Pokemon Crystal", vbaPath},
  {gen3 & "Ruby\Pokemonruby.zip", "Pokemon Ruby", vbaPath},
  {gen3 & "Sapphire\Pokemonsapphire.zip", "Pokemon Saphire", vbaPath},
  {gen3 & "Emerald\Pokemonemerald.zip", "Pokemon Emerald", vbaPath},
  {gen3 & "FireRed\Pokemonfirered.zip", "Pokemon Fire Red", vbaPath},
  {gen3 & "LeafGreen\Pokemonleafgreen.zip", "Pokemon Leaf Green", vbaPath},
  {gen4 & "Diamond\Pokemondiamond.nds", "Pokemon Diamond", desumePath},
  {gen4 & "Perl\Pokemonperl.nds", "Pokemon Perl", desumePath},
  {gen4 & "Platinum\Pokemonplatinum.zip", "Pokemon Platinum", desumePath},
  {gen4 & "HeartGold\Pokemonheartgold.zip", "Pokemon Heart Gold", desumePath},
  {gen4 & "SoulSilver\Pokemonsoulsilver.zip", "Pokemon Black", desumePath},
  {gen5 & "Black\pokemonblack.nds", "Pokemon Black", desumePath},
  {gen5 & "White\Pokemonwhite.nds", "Pokemon White", desumePath},
  {mysteryDungeon &  "MysteryDungeonRedRescueTeam\PokemonMysteryDungeon-RedRescueTeam.zip",  "Mystery Dungeon Red Rescue Team", vbaPath},
  {mysteryDungeon &  "MysteryDungeonBlueRescueTeam\PokemonMysteryDungeon-BlueRescueTeam.nds",  "Mystery Dungeon Blue Rescue Team", desumePath},
  {mysteryDungeon &  "MysteryDungeonExplorersofTime\MysteryDungeonExplorersofTime.7z",  "Mystery Dungeon Explorers of Time", desumePath},
  {mysteryDungeon &  "MysteryDungeonExplorersofDarkness\MysteryDungeonExplorersofDarkness.7z",  "Mystery Dungeon Explorers of Darkness", desumePath},
  {mysteryDungeon &  "MysteryDungeonExplorersofSky\MysteryDungeonExplorersofsky.7z",  "Mystery  Dungeon Explorers of Sky", desumePath},
  {spinoff &  "TradingCardGame\TradingCardGame.zip", "Pokemon Trading Card Game",  vbaPath},
  {spinoff & "Pinball\Pinball.zip", "Pokemon Pinball", vbaPath},
  {spinoff &  "PinballRubySapphire\PinballRubySapphire.zip", "Pinball Ruby Sapphire",  vbaPath},
  {spinoff  &  "PuzzleChallenge\PuzzleChallenge.zip", "Pokemon Puzzle  Challenge",  vbaPath},
  {ranger & "Ranger\PokemonRanger.NDS", "Pokemon Ranger", desumePath},
  {ranger &  "Ranger2ShadowsofAlmia\RangerShadowsofAlmia.zip", "Pokemon Ranger 2  Shadows of Almia", desumePath},
  {ranger &  "Ranger3GuardianSigns\RangerGuardianSigns.zip", "Pokemon Ranger 3  Guardian Signs", desumePath}}
The above code basically sets some variables and then I put them into an array. You could technically not do this and just put everything into the array as just a string but for me it was just easier this way, incase I changed a path or something, I didn't want to have to do that on every element.


I wrote all of the button generation in a sub and then called it on form load. You don't have to do this but for the sake of being able to use it somewhere else, I chose to do it this way.


Code:
  Private Sub Form1_Load(sender As System.Object, e As System.EventArgs) Handles MyBase.Load
  CreateGameButtons()
  End Sub
Now for the generation part. Parts of this might not make sense since a few of the things I am referencing are included as a resource to the project, which will be the next part to this. The only reason I am including them here is because without them parts that are to come more then likely won't make sense.


Code:
  Private Sub CreateGameButtons()
  Dim gameImage(30) As Image
  gameImage(0) = My.Resources.Red
  gameImage(1) = My.Resources.Blue
  gameImage(2) = My.Resources.Yellow
  gameImage(3) = My.Resources.Green_jp
  gameImage(4) = My.Resources.Gold
  gameImage(5) = My.Resources.Silver
  gameImage(6) = My.Resources.Crystal
  gameImage(7) = My.Resources.Ruby
  gameImage(8) = My.Resources.Saphire
  gameImage(9) = My.Resources.Emerald
  gameImage(10) = My.Resources.Fire_Red
  gameImage(11) = My.Resources.Leaf_Green
  gameImage(12) = My.Resources.Diamond
  gameImage(13) = My.Resources.Pearl
  gameImage(14) = My.Resources.Platinum
  gameImage(15) = My.Resources.Heart_Gold
  gameImage(16) = My.Resources.Soul_Silver
  gameImage(17) = My.Resources.Black
  gameImage(18) = My.Resources.White
  gameImage(19) = My.Resources.Mystery_Dungeon_1_Red_Rescue_Team
  gameImage(20) = My.Resources.Mystery_Dungeon_1_Blue_Rescue_Team
  gameImage(21) = My.Resources.Mystery_Dungeon_2_Explorers_of_Time
  gameImage(22) = My.Resources.Mystery_Dungeon_2_Explorers_of_Darkness
  gameImage(23) = My.Resources.Mystery_Dungeon_3_Explorers_of_Sky
  gameImage(24) = My.Resources.Trading_Card_Game
  gameImage(25) = My.Resources.Pinball
  gameImage(26) = My.Resources.Pinball_Ruby_Saphire
  gameImage(27) = My.Resources.Puzzle_Challenge
  gameImage(28) = My.Resources.Ranger_1
  gameImage(29) = My.Resources.Ranger_2_Shadows_of_Almia
  gameImage(30) = My.Resources.Ranger_3_Guardian_Signs
This array is going to be for the button images. Each image is a resource in the project and if you were to add them as such, this is how you would grab them.


Code:
  Dim nextButton As Integer = 3
  'Since this will include the 31 games that we currently have, thats what the upper bounds will be.
  'Dynamic buttons are going to be created for each game and information for the buttons will be pulled from the array.


  For i As Integer = 0 To gameInfo.GetUpperBound(0)
  Dim pokeButton As New Button
  Dim getGamePath As String
  Dim getGameName As String()
  'These will never change
  pokeButton.Text = "" ' This will never be set since we are using an image
   
  pokeButton.Size = New Size(150, 150) 'Size of the button
  getGamePath = gameInfo(i, 0).ToString
  getGameName = getGamePath.Split("\")


  getGamePath = getGameName(3) ' Name of the game that we are going to use for the button control
  'Once we get it we are going to create the control


  pokeButton.Name = "btn_" & getGamePath
  pokeButton.Image = gameImage(i)
  pokeButton.Location = New Point(nextButton, 3)
  pokeButton.Visible = True


  AddHandler pokeButton.Click, AddressOf StartGame
  AddHandler pokeButton.MouseHover, AddressOf Gameinformation


  pan_games.Controls.Add(pokeButton)
  pan_games.Refresh()
  Me.Refresh()


  nextButton += 155
  Next
  End Sub
I'll break down what most of this does.
Code:
Dim nextButton As Integer = 3
This is going to be the starting point for our buttons. This just means it it starting 3 pixels in from the left of the screen.


Code:
For i As Integer = 0 To gameInfo.GetUpperBound(0)


  Dim pokeButton As New Button


  Dim getGamePath As String


  Dim getGameName As String()
This is the start of our loop. We are taking the maximum number of elements in out array (getupperbound) and looping through those till we get to the end. We declare our variables , one for the button , gamepath and name.


Code:
getGamePath = gameInfo(i, 0).ToString


  getGameName = getGamePath.Split("\")


  getGamePath = getGameName(3) ' Name of the game that we are  going to use for the button control
Now we are going to pull some information from out first array. We want the game path so we know where to go when the button will be pressed. Also we are going to grab the game name from that same string and use that for the button name since they must be unique. I figured this would be a good way to do it.


.Split splits strings that are from the character we are looking for which in this case is "\" So we end up with an array of strings. For instance:
gen1 & "Blue\Pokemonblue.zip"


Would actually look like this:
Resources\Roms\GenerationI\Blue\Pokemonblue.zip


The way split works is that it removed "\" and takes everything else and puts it into an array.
So we end up with


0 Reourcese
1 Roms
2 Generation
3 Blue
4 Pokemonblue.zip


This makes more sense when we move onto the next part because we are going to be using the 4th element (which in this case is really the one that is labeled 4 since 0 counts as 1.
Code:
getGamePath = getGameName(3) '
This takes the 4th element, which would be Blue and and sets the game name variable to it.


Code:
AddHandler pokeButton.Click, AddressOf StartGame


  AddHandler pokeButton.MouseHover, AddressOf  Gameinformation
These are our event handlers. By default these newly created buttons can't do anything. So we have to write up some events and wire them together with these. This will come a little later.


Code:
pan_games.Controls.Add(pokeButton)


  pan_games.Refresh()
Now we need to add the new button to the form or in this case I added them to a panel.


Now for the button code.
Code:
  Private Sub StartGame(ByVal sender As System.Object, ByVal e As System.EventArgs)
  Dim getbuttonName As String = CType(sender, Button).Name
  Dim getGamePath As String = ""
  Dim initialGameName As String = ""
  Dim gamePathArray As String()
  Dim programStart As String = ""
  Dim i As Integer = 0
  getbuttonName = getbuttonName.Substring(4)


  Do Until getbuttonName = initialGameName
  getGamePath = gameInfo(i, 0).ToString
  gamePathArray = getGamePath.Split("\")


  initialGameName = gamePathArray(3)


  i += 1
  Loop
  i -= 1
  programStart = gameInfo(i, 2).ToString
  Process.Start(programStart, getGamePath)
  End Sub
There is quiet a bit to this one. So lets break it down a bit.
Code:
Dim getbuttonName As String = CType(sender,  Button).Name
This line here is how we find out what button is calling this sub, since each button that is created uses this, we need to know what one it was. This is why I used the game name as the button name because it would be easier later for when we need to launch the game.


The do until loop loops through the array till it finds a match. Once it finds a match we know what game to start.


Now for the mouse over event.
Code:
  Private Sub Gameinformation(ByVal sender As System.Object, ByVal e As System.EventArgs)
  Dim getbuttonName As String = CType(sender, Button).Name


  Dim getGamePath As String = ""
  Dim initialGameName As String = ""
  Dim gamePathArray As String()
  Dim i As Integer = 0
  Dim getGameIndex As Integer


  getbuttonName = getbuttonName.Substring(4)


  Do Until getbuttonName = initialGameName
  getGamePath = gameInfo(i, 0).ToString
  gamePathArray = getGamePath.Split("\")
  getGameIndex = i
  initialGameName = gamePathArray(3)


  i += 1
  Loop
  i -= 1
  pct_boxArt.BackgroundImage = gameBackCovers(i)
  pct_boxArt.BackgroundImageLayout = ImageLayout.Stretch
  End Sub
This works just the same as the onclick event. We do some searching through an array till we find a match. Once a match is found we set the picture box to match the cover for the game that we moused over on.
 
Z61

Z61

Some times our saints are sinners
Retired
Programmer Forum Addict Odysseus' Summit
Messages
5,476
Reaction score
3,422
You should try to tidy your code up as this just looks nasty.
 
Top Bottom