Sometimes things (PowerShell?) gets too smart on me...
In this case, I would like change the Text
property of a WinForms ListBox
item by its index (not the SelectedItems
). The point here is that $ListBox.Items[$CurrentIndex]
returns a [string]
type rather than an [Item]
type...
For this I have created a mcve (with a context menu) out of my bigger project:
using namespace System.Windows.Forms
$Form = [Form]@{ StartPosition = 'CenterScreen' }
$ListBox = [ListBox]@{}
@('one', 'two', 'three').ForEach{ $Null = $ListBox.Items.Add($_) }
$Form.Controls.Add($ListBox)
$ListBox.ContextMenuStrip = [ContextMenuStrip]@{}
$Context = $ListBox.ContextMenuStrip.Items.Add('ToUpper')
$ListBox.Add_MouseDown({ param($s, $e)
if ($e.Button -eq 'Right') { $Script:CurrentIndex = $ListBox.IndexFromPoint($e.Location) }
})
$Context.Add_Click({ param($s, $e)
if ($Null -ne $CurrentIndex) {
$Text = $ListBox.Items[$CurrentIndex]
Write-Host "I want to change text ""$Text"" of the item #$CurrentIndex to: ""$($Text.ToUpper())"""
# $ListBox.Items.Item[$CurrentIndex].Text = $Text.ToUpper()
}
})
$Form.ShowDialog()
How can I change the text of e.g. $ListBox.Items[1]
("two
") to e.g. "TWO
"?
I am actually not sure whether this is PowerShell related issue (similar to #16878
Decorate dot selected Xml
strings (leaves) with XmlElement
methods where I would have an option to use the SelectNodes()
method) or related to WinForms itself: The answer might be in Gwt Listbox item reference to an Object in which case I have no clue how translate this to PowerShell.
CodePudding user response:
You could modify the stored item value with $ListBox.Items.Item($CurrentIndex) = $Text.ToUpper()
- but modifying a collection item in place is not going to trigger re-drawing the ListBox
control, so it'll look like no change took place.
Instead, modify the collection itself - remove the old entry and insert a new one at the same position:
$Context.Add_Click({ param($s, $e)
if ($Null -ne $CurrentIndex) {
$Text = $ListBox.Items[$CurrentIndex]
# Remove clicked item
$ListBox.Items.RemoveAt($CurrentIndex)
# Insert uppercased string value as new item at the same index
$ListBox.Items.Insert($CurrentIndex, $Text.ToUpper())
}
})
This will cause the owning control to refresh and the change will be reflected in the GUI immediately