有時事情(PowerShell?)對我來說太聰明了......
在這種情況下,我想更改由其索引(而不是Text)選擇的 WinForms 項的屬性。這里的重點是它似乎是一種型別而不是一種型別......
為此,我從我的更大專案中創建了一個mcve(帶有背景關系選單):ListBoxSelectedItems$ListBox.Items[$CurrentIndex][string][Item]
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.ToUpper()
}
})
$Form.ShowDialog()
如何將例如$ListBox.Items[1](“ two”)的文本更改為例如“ TWO”?
我實際上不確定這是與 PowerShell 相關的問題(類似于使用我可以選擇使用該方法的方法#16878裝飾點選擇的Xml字串(葉子)XmlElementSelectNodes())還是與 WinForms 本身有關:答案可能在Gwt Listbox 專案參考中一個物件,在這種情況下,我不知道如何將其轉換為 PowerShell。
uj5u.com熱心網友回復:
您可以使用 -修改存盤的專案值,$ListBox.Items.Item($CurrentIndex) = $Text.ToUpper()但就地修改集合專案不會觸發重新繪制ListBox控制元件,因此看起來沒有發生任何更改。
相反,修改集合本身 - 洗掉舊條目并在同一位置插入一個新條目:
$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())
}
})
這將導致擁有的控制元件重繪 ,并且更改將立即反映在 GUI 中
uj5u.com熱心網友回復:
為了補充Mathias R. Jessen 的有用答案:
事實上,問題不在于.Items集合本身的修改——$ListBox.Items[$CurrentIndex] = $Text.ToUpper()作業得很好。[1]
為了解決真正的問題 -ListBox不重繪 以回應修改基礎集合中的現有專案(即使您呼叫也不重繪 ),還有一種替代洗掉和重新添加專案的方法:.Items$ListBox.Refresh()
您可以通過將實體分配給串列框的屬性來使用資料系結。System.ComponentModel.BindingList`1.DataSource
就地修改item后,可以呼叫.ResetBindings()方法讓listbox自行重繪 ,如下圖。
筆記:
還有一種
.ResetItem(int index)方法旨在執行特定于專案的重繪 ,但我無法讓它作業;關于為什么受到贊賞的指標。.ResetBindings()可以改變串列框的滾動狀態,這就是下面的代碼顯式保存和恢復它的原因。但是,它確實會自動保留串列框的選擇狀態(洗掉和重新添加方法也必須手動管理)。
using namespace System.Windows.Forms
using namespace System.ComponentModel
Add-Type -AssemblyName System.Windows.Forms
$Form = [Form]@{ StartPosition = 'CenterScreen' }
$ListBox = [ListBox]@{}
# Define the items as a strongly typed array of item strings.
[string[]] $items = @('one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight')
# Wrap the array in a [BindingList[string]] instance
# and make it the listbox's data source.
$ListBox.DataSource = [BindingList[string]]::new($items)
$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) {
# Modify the underlying array.
$items[$CurrentIndex] = $items[$CurrentIndex].ToUpper()
# To prevent unwanted scrolling during the refresh below,
# save and restore what item is currently shown at the top
# of the visible list portion.
$prevTopIndex = $ListBox.TopIndex
# Notify the listbox via the BindingList[string] instance that
# the items have changed.
# !! The following *item-specific* call does NOT work.
# !! $ListBox.DataSource.ResetItem($CurrentIndex)
$ListBox.DataSource.ResetBindings()
$ListBox.TopIndex = $prevTopIndex # Restore the scrolling state.
}
})
$Form.ShowDialog()
[1] 一般語法觀察:詳細的替代方法是顯式呼叫.Item實作提供基于索引的訪問的引數化屬性$ListBox.Items.Item($CurrentIndex)的方法: 。這適用于任何IList實作集合型別,包括陣列。但是,通常不需要這樣做,因為 PowerShell 通過直接索引顯示此類引數化屬性。例如,給定一個陣列$a = 'foo', 'bar',$a.Item(1)更自然地表示為$a[1]
轉載請註明出處,本文鏈接:https://www.uj5u.com/houduan/432581.html
標籤:电源外壳 表格 powershell-5.1
