【问题标题】:PowerShell WPF - Binding DataGrid ComboBox to Column In ItemsSourcePowerShell WPF - 将 DataGrid ComboBox 绑定到 ItemsSource 中的列
【发布时间】:2020-01-30 20:14:22
【问题描述】:

我正在尝试使用给定列中的唯一值填充 DataGrid 中的 ComboBox,但是我得到了意想不到的结果,因为它将该行中的值拆分为单个字符并用所述字符填充每个 ComboBox。

这是我的问题的一个简单示例脚本;

$csv = "ID,Fruit,Owner`r`n"
$csv += "1,Apple,Andrew`r`n"
$csv += "2,Banana,Bill`r`n"
$csv += "3,Cherry,Charles`r`n"
$csv += "4,Date,Daniel`r`n"
$csv += "5,Elderberry,Ethan`r`n"

$data = ConvertFrom-Csv $csv

$inputXML = @"
<Window x:Name="DataGridComboTest" x:Class="DataGridComboTest.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="DataGridComboTest" Width="640" Height="480" WindowStartupLocation="CenterScreen">
    <Grid>
        <DataGrid x:Name="DataGrid" Margin="10,10,10,10" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Binding="{Binding ID}" Header="ID"/>
                <DataGridTextColumn Binding="{Binding Fruit}" Header="Fruit"/>
                <DataGridTextColumn Binding="{Binding Owner}" Header="Owner"/>

                <DataGridTemplateColumn Header="Owner Combo">
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox
                                SelectedItem="{Binding Path=Owner, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                ItemsSource="{Binding Owner}"
                                Text="{Binding Path=Owner, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                            </ComboBox>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
"@

$inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N'  -replace '^<Win.*', '<Window'
[void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
[xml]$XAML = $inputXML

$reader=(New-Object System.Xml.XmlNodeReader $xaml)
$Form=[Windows.Markup.XamlReader]::Load( $reader )
$xaml.SelectNodes("//*[@Name]") | %{ Set-Variable -Name "$($_.Name)" -Value $Form.FindName($_.Name) -ErrorAction Stop }

$DataGrid.ItemsSource = $data

$Form.ShowDialog() | Out-Null

我想做的是从表中的现有所有者中为每个水果选择一个不同的所有者,但是我可以选择相邻所有者名称中的每个字母;

【问题讨论】:

    标签: wpf powershell data-binding combobox datagrid


    【解决方案1】:

    您应该将ItemsSource 绑定到IEnumerable&lt;string&gt;,而不是标量string(即IEnumerable&lt;char&gt;)。

    试试这样的:

    ...
    ItemsSource="{DynamicResource owners}"
    ...
    
    $owners = $data | Select-Object -ExpandProperty Owner -Unique
    $Form.Resources.Add("owners", $owners)
    

    【讨论】:

    • 感谢您的回复。你测试了吗?它为我抛出了一个关于缺少括号的错误。我试过改变它,但我不能让它工作。
    • 您使用 DynamicResource 绑定为我指明了正确的方向。我将所有者行简化为“$owners = $data | Select-Object -ExpandProperty Owner -Unique”,这似乎可行 - 我现在在每个组合中都获得了所有唯一所有者。
    • @Valiante:我已经从我的回答中删除了对ToArray() 的调用。而且您有重复的事实与原始问题无关。
    • 当它给我一个错误时,我完全不能良心赞成或接受它作为答案。我写了自己的答案来展示你帮助我实现的完整最终解决方案,感谢你,但我没有接受它作为答案,因为我想让你有机会编辑。我还提到了重复项,只是因为我最初有没有 -unique 的行,但在现实世界的场景中,当我只想要唯一的所有者(如原始帖子中所述)时,这包括每个名称的次数与它在数据中出现的次数一样多。
    • @Valiante:说得好。我也在答案中添加了 -Unique 开关。
    【解决方案2】:

    mm8 的帮助下,我能够想出一个工作脚本;

    $csv = "ID,Fruit,Owner`r`n"
    $csv += "1,Apple,Andrew`r`n"
    $csv += "2,Banana,Bill`r`n"
    $csv += "3,Cherry,Charles`r`n"
    $csv += "4,Date,Daniel`r`n"
    $csv += "5,Elderberry,Ethan`r`n"
    $csv += "6,Fig,Bill`r`n"
    $csv += "7,Grape,Daniel`r`n"
    
    $data = ConvertFrom-Csv $csv
    
    $inputXML = @"
    <Window x:Name="DataGridComboTest" x:Class="DataGridComboTest.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            Title="DataGridComboTest" Width="640" Height="480" WindowStartupLocation="CenterScreen">
        <Grid>
            <DataGrid x:Name="DataGrid" Margin="10,10,10,10" AutoGenerateColumns="False">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding ID}" Header="ID"/>
                    <DataGridTextColumn Binding="{Binding Fruit}" Header="Fruit"/>
                    <DataGridTextColumn Binding="{Binding Owner}" Header="Owner"/>
    
                    <DataGridTemplateColumn Header="Owner Combo">
                        <DataGridTemplateColumn.CellTemplate>
                            <DataTemplate>
                                <ComboBox
                                    SelectedItem="{Binding Path=Owner, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
                                    ItemsSource="{DynamicResource owners}"
                                    Text="{Binding Path=Owner, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
                                </ComboBox>
                            </DataTemplate>
                        </DataGridTemplateColumn.CellTemplate>
                    </DataGridTemplateColumn>
                </DataGrid.Columns>
            </DataGrid>
        </Grid>
    </Window>
    "@
    
    $inputXML = $inputXML -replace 'mc:Ignorable="d"','' -replace "x:N",'N'  -replace '^<Win.*', '<Window'
    [void][System.Reflection.Assembly]::LoadWithPartialName('presentationframework')
    [xml]$XAML = $inputXML
    
    $reader=(New-Object System.Xml.XmlNodeReader $xaml)
    $Form=[Windows.Markup.XamlReader]::Load( $reader )
    $xaml.SelectNodes("//*[@Name]") | %{ Set-Variable -Name "$($_.Name)" -Value $Form.FindName($_.Name) -ErrorAction Stop }
    
    $DataGrid.ItemsSource = $data
    
    #$owners = [Linq.Enumerable]::ToArray($data | Select-Object -ExpandProperty Owner)
    $owners = $data | Select-Object -ExpandProperty Owner -Unique
    $Form.Resources.Add("owners", $owners)
    
    $Form.ShowDialog() | Out-Null
    

    DynamicResource 绑定是关键,但 mm8 答案中的 [Linq.Enumerable] 行引发了错误。然而,简化它以从 $data 中选择唯一所有者解决了这个问题。我还在源数据中添加了几个重复的所有者,以更准确地模拟真实场景,因此是“-Unique”。

    【讨论】:

      猜你喜欢
      • 2011-09-01
      • 2010-12-02
      • 2015-04-07
      • 2011-08-23
      • 2013-06-30
      • 2023-03-07
      • 2016-04-30
      • 2011-12-17
      • 2015-11-22
      相关资源
      最近更新 更多