【发布时间】:2020-06-19 18:13:30
【问题描述】:
所以,我正在尝试使用 WPF 表单为搜索应用程序创建 GUI。我的表单有一个 TextBox 和 ComboBox 用于输入,每次更改事件触发时,内容都会作为过滤器应用。 $var_SearchRegion 是我的 ComboBox,$var_SearchFor 是我的 TextBox,$var_DGDisplay 是我用于返回数据的 DataGrid。
为了设置过滤器,我创建了一个基本函数。我知道有比 If Then ElseIf 树更干净的方法来做到这一点,但这很快而且有效。函数如下所示:
Function GetFilteredItems
{
$RSelect = $var_SearchRegion.SelectedValue.Content
$PF = $var_SearchFor.Text
$RF = If ($RSelect -eq 'All Regions') {''} Else {$RSelect}
If ($PF -eq '' -and $RF -eq '')
{
$DPST
}
ElseIf ($PF -eq '')
{
$DPST | ? {$_.Region -eq $RF}
}
ElseIf ($RF -eq '')
{
$DPST | ? {$_.FilePath -like "*$PF*"}
}
Else
{
$DPST | ? {$_.Region -eq $RF -and $_.FilePath -like "*$PF*"}
}
}
当过滤器将数据集减少到一个条目并将其返回时,就会出现此问题。我之前在使用 .NET 方法的 PowerShell 中遇到过这个问题,我假设类型从“某物”的 [Array] 更改为“某物”,这会导致 WPF 对象出现问题。
这是一个事件处理程序代码的示例,当过滤器将我的返回设置为 1 项时会导致问题:
$var_SearchFor.Add_TextChanged({
$var_DGDisplay.ItemsSource = GetFilteredItems
$var_DGDisplay.Refresh
})
当GetFilteredItems 返回 1 项时,我收到此错误:
Exception setting "ItemsSource": "Cannot convert the "@{Region=SW;
FilePath=\\server\share\folder\file.ext}" value of type
"Deserialized.System.Management.Automation.PSCustomObject" to type "System.Collections.IEnumerable"."
At C:\Users\Matthew\GUITest.ps1:90 char:5
+ $var_DGDisplay.ItemsSource = GetFilteredItems
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
+ FullyQualifiedErrorId : ExceptionWhenSetting
我可以通过包装函数调用并显式转换为 [array] 类型来轻松“修复”这个问题,如下所示:
$var_SearchFor.Add_TextChanged({
$var_DGDisplay.ItemsSource = [array](GetFilteredItems)
$var_DGDisplay.Refresh
})
但是不得不这样做感觉倒退了。我应该能够以某种方式在函数内部解决这个问题。但是,用相同的[array]() 包装函数的输出行(在 4 个位置)并没有成功。我找到了有关 PowerShell 高级函数的一些信息,我可以在其中使用语法 [OutputType([Array])] 来指定输出类型,但即使我使用 (Get-Command GetFilteredItems).OutputType 验证了我的输出类型是 System.Array,它仍然会失败同样的错误。
TL;DR - 有没有办法避免使用 [array]() 包装我的函数调用并仍然使其与我的 WPF DataGrid 控件的 ItemSource 属性一起使用?
【问题讨论】:
-
我一直这样做是因为 PowerShell 在幕后经常使用赋值来创建返回对象,例如:$return = Cmd.如果命令的结果是一个数组,它会这样返回。如果它只是一个项目,它将作为类型变量返回,无论对象是什么。为了解决这个问题,我总是使用: $return = @(Cmd)
-
@thepip3r,虽然您在 净效应 方面是正确的,但这并不是它在幕后工作的方式 - 请参阅 stackoverflow.com/a/60020105/45375
标签: arrays .net wpf powershell return