Trying to learn and understand PowerShell better, I am trying to build a vocabulary trainer using forms in PowerShell.
The Vocabulary is stored in different topics, where each topic is stored in a hashtable.
Maybe I am approaching this the wrong way, but trying to work with the Listbox Item, I am not able to figure out, how to transfer the code in such way, that it goes into the correct Hashtable and shows the first Key.
I tried to combine several strings and tried to use Pipe to transfer the listbox item. Either ways I failed. Please have a look at the code, so I can further explain.
CLS
Add-Type -assembly System.Windows.Forms
$Script:Counter = 1
$Weekdays = [ordered]@{Monday = 'Montag';Tuesday = 'Dienstag';Wednesday = 'Mittwoch'}
$Months = [ordered]@{January = 'Januar';February = 'Februar';March = 'März'}
$Numbers =[ordered]@{One = 'Eins';Zwei = 'Two';Drei = 'Three'}
$Vocabulary = @{Weekdays = '$Weekdays';Months = '$months';Numbers = '$Numbers'}
$Main_Form = New-Object System.Windows.Forms.Form
$Main_Form.Icon = $objIcon
$Main_Form.Text ='Test Test Test'
$Main_Form.Size = '1000,600'
$Main_Form.StartPosition = "CenterScreen"
$Main_Form.AutoSize = $true
$Main_Form.BringToFront()
$Label = New-Object System.Windows.Forms.label
$Label.Location = '10,20'
$Label.Size = '200,60'
$Label.Font = New-Object System.Drawing.Font("Times New Roman",16,[System.Drawing.FontStyle]::Bold)
$Label.BackColor = "Transparent"
$Label.ForeColor = "Blue"
$Label.Text = 'Counter '+$Script:Counter
$Main_Form.Controls.Add($Label)
$ListBox = New-Object System.Windows.Forms.ListBox
$ListBox.Location = '20,80'
$ListBox.Size = '300,50'
$ListBox.Font = New-Object System.Drawing.Font("Times New Roman",20,[System.Drawing.FontStyle]::Bold)
$ListBox.Height = 150
$ListBox.items.AddRange($Vocabulary.Keys)
$Main_Form.Controls.Add($ListBox)
$Labelannouncement = New-Object System.Windows.Forms.label
$Labelannouncement.Location = '400,80'
$Labelannouncement.Size = '400,60'
$Labelannouncement.Font = New-Object System.Drawing.Font("Times New Roman",18,[System.Drawing.FontStyle]::Bold)
$Labelannouncement.BackColor = "Transparent"
$Labelannouncement.ForeColor = "Black"
$Labelannouncement.Text = 'Nothing chosen yet'
$Main_Form.Controls.Add($Labelannouncement)
$LabelContent = New-Object System.Windows.Forms.label
$LabelContent.Location = '400,160'
$LabelContent.Size = '400,60'
$LabelContent.Font = New-Object System.Drawing.Font("Times New Roman",18,[System.Drawing.FontStyle]::Bold)
$LabelContent.BackColor = "Transparent"
$LabelContent.ForeColor = "Black"
$Main_Form.Controls.Add($LabelContent)
$Labeltest = New-Object System.Windows.Forms.label
$Labeltest.Location = '400,250'
$Labeltest.Size = '400,60'
$Labeltest.Font = New-Object System.Drawing.Font("Times New Roman",18,[System.Drawing.FontStyle]::Bold)
$Labeltest.BackColor = "Transparent"
$Labeltest.ForeColor = "Red"
$Labeltest.Text = 'Test'
$Main_Form.Controls.Add($Labeltest)
$Button = New-Object System.Windows.Forms.Button
$Button.Location = '50,250'
$Button.Size = '200,75'
$Button.Font = New-Object System.Drawing.Font("Arial",16,[System.Drawing.FontStyle]::Bold)
$Button.Text = 'Next'
$Main_form.Controls.Add($Button)
$ButtonClickEvent = {
$Script:Counter++
$Label.Text = "Counter $Script:Counter"
$Labelannouncement.Text = $Listbox.SelectedItems
$Labeltest.Text = ''
}
$Button.Add_Click($ButtonClickEvent)
$Main_Form.ShowDialog()
The Idea is, that when running the script, in the Listbox, I can choose from the 3 items. The target would be, that as soon as I have chosen one of the items, I would like to have the first Key of the related hashtable. So when I am choosing Weekdays, and press onto the Next button, the red Test should be replaced with "Monday".
The reason for the Hashtable called "$Vocabulary" is, to get the value:
$Vocabulary.item($Listbox.SelectedItem)
But now comes the question. To use the above example with "Monday", I would have to use the following code:
$($months.Keys)[0]
And here is the problem I am fighting with.
Do I have to pipe or to combine the result from the listbox.item and pass it on and how would I do that? For a test, I tried to add it as text to the last line.
$ButtonClickEvent = {
$Script:Counter++
$Label.Text = "Counter $Script:Counter"
$Labelannouncement.Text = $Listbox.SelectedItems
$Labeltest.Text = ''
So that when pressing onto Weekdays and then pressing the Next button, I would receive Monday as a red text.
Trying
$({$Vocabulary.item($Listbox.SelectedItem)}.Values)[0]
Did give me an index into a null array error and working with pipes, I haven't understood, how I would transfer to, so it does the same like:
$($months.Values)[0]
and the attempt using:
$($_.Values)[0]
Didn't help. Is there a way to solve this or is it a wrong attempt?
Thank you for any help, much appreciated
Mike
I would not store hashtables inside the $Vocabulary
hashtable, but instead add arrays under each Key:
$Weekdays = 'Montag','Dienstag','Mittwoch'
$Months = 'Januar','Februar','März'
$Numbers = 'Eins','Zwei','Drei'
$Vocabulary = @{Weekdays = $Weekdays; Months = $Months; Numbers = $Numbers}
Next, change the $ButtonClickEvent
to become
$ButtonClickEvent = {
$Script:Counter++
$Label.Text = "Counter $Script:Counter"
$Labelannouncement.Text = $Listbox.SelectedItem
$Labeltest.Text = $Vocabulary[$Listbox.SelectedItem][0]
}
$Listbox.SelectedItem
(singular) gets the key name of the Vocabulary the user is interested in. $Vocabulary
stores arrays under each key, and you want to show the first one, so simply use index [0] of the first item.P.S. When done, don't forget to clean up the form with $Main_Form.Dispose()
Hope that helps