简体   繁体   English

PowerShell WPF - 将 DataGrid ComboBox 绑定到 ItemsSource 中的列

[英]PowerShell WPF - Binding DataGrid ComboBox to Column In ItemsSource

I am trying to populate a ComboBox within a DataGrid with unique values from a given column, however I'm getting unexpected results in that it splits the value from that row into individual characters and populates each ComboBox with said characters.我正在尝试使用给定列中的唯一值填充 DataGrid 中的 ComboBox,但是我得到了意想不到的结果,因为它将该行中的值拆分为单个字符并用所述字符填充每个 ComboBox。

Here's a simple example script of my issue;这是我的问题的一个简单示例脚本;

$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

What I'd like to be able to do is select a different owner for each fruit from the existing owners in the table, however instead I'm given a choice of each letter in the adjacent owner's name;我想做的是 select 表中现有所有者的每种水果的不同所有者,但是相反,我可以选择相邻所有者姓名中的每个字母;

示例截图

You should bind the ItemsSource to an IEnumerable<string> rather than a scalar string (which is an IEnumerable<char> ).您应该将ItemsSource绑定到IEnumerable<string>而不是标量string (即IEnumerable<char> )。

Try something like this:尝试这样的事情:

...
ItemsSource="{DynamicResource owners}"
...

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

With mm8 's help I was able to come up with a working script;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

The DynamicResource binding was key, but the [Linq.Enumerable] line from mm8's answer threw an error. DynamicResource 绑定是关键,但 mm8 的答案中的 [Linq.Enumerable] 行引发了错误。 However simplifying it to select unique owners from $data resolved this.但是,将其简化为来自 $data 的 select 唯一所有者解决了这个问题。 I also added a couple of duplicate owners to the source data to more accurately simulate a real-world scenario, hence "-Unique".我还在源数据中添加了几个重复的所有者,以更准确地模拟真实世界的场景,因此是“-Unique”。

DataGridCombo 工作示例

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM