如何为 DataGridTemplate 中的每个组合框 change/prepopulate SelectedIndex?

How to change/prepopulate SelectedIndex for each individual Combobox in DataGridTemplate?

我目前有一个包含 2 列的 DataGrid,其中一列是 DataGridTextColumn,它将显示字符串 ObservableCollection 中的项目,第二列是 DataGridTemplateColumn,其中包含 DataGridCellTemplate,其中包含显示 Combobox 的 DataTemplate .组合框还绑定到字符串的 ObservableCollection。一切都按应有的方式绑定和显示。

我想要实现的是,由于需求的变化和功能的增加,我需要更改显示在组合框(当前索引为 0)。我有一个新字典,其中包含第一列中的条目作为键,值是存在于第二列(组合框)中的字符串。

即: 如何将第二列中某些组合框的 selectedIndex 更改为 'pre-select' 从字典中获取的已知条目的索引?

一个最小的、完整的、可验证的例子:

我目前拥有的:

+--------------+-------------------+
| CustomerName |     Location      |
+--------------+-------------------+
| Bob          | <Select Location> |   <-- these are comboboxes
| John         | <Select Location> |
| Katy         | <Select Location> |
+--------------+-------------------+

XAML:

<DataGrid x:Name="CustomerLocationGrid" Height="265" VerticalAlignment="Center" Margin="-7,8,-2,-6" ItemsSource="{Binding CustomerNameList}" AutoGenerateColumns="False"> 
 <DataGrid.Columns>
     <DataGridTextColumn x:Name="customerDisplayList" Header="CustomerName" MinWidth="500" IsReadOnly="True"  Binding="{Binding Path=., Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" DisplayIndex="0"/>
     <DataGridTemplateColumn x:Name="networkTypeTemplateColumn" Header="Location" MinWidth ="200" CanUserResize="True" Width="*">
           <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                     <ComboBox x:Name="locationCombobox"  ItemsSource="{Binding locationList, RelativeSource={RelativeSource AncestorType=UserControl}}" SelectedIndex="0" SelectionChanged="locationCombobox_SelectionChanged"/>
                 </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
     </DataGridTemplateColumn>
   </DataGrid.Columns>

其中:

public ObservableCollection<String> CustomerNameList { get; set; }    //has a collection of Bob, John, Katy
public ObservableCollection<string> locationList { get; set;}   //has locations like Minnesota, Iowa, New York

(列表来自不同的来源)

注意上面的 DataTemplate-Combobox XAML 是我从 this tutorial on WPF comboboxes(名为 "The Best WPF Combobox Tutorial Ever")

那里学到的

以及我如何从另一个来源获得第三个 Dictionary<string,string>,它具有 Bob -> MinnesotaJohn -> Iowa 的映射,但 Katy 不在那里,因为它无法预先确定并且用户需要手动 select 位置。

我想自动 select 组合框内的索引 以便 table 看起来像这样,或者更改 Bob 和 Johns 的位置:

+--------------+-------------------+
| CustomerName |     Location      |
+--------------+-------------------+
| Bob          | Minnesota         | <-- set as the displayedIndex
| John         | Iowa              |
| Katy         | <Select Location> |
+--------------+-------------------+

我试过的: 我的方法是遍历每个 CustomerName 条目,在字典中查找它,如果从字典返回一个值,则设置位置。字符串都是相同的,因此不需要匹配。

我也尝试过使用相关的解决方案,如 ,但觉得它太复杂了(也无法获得父级)和其他一些基于 VisualTreeHelper 方法的解决方案。

如果您使用 NameLocation 属性 创建一个 Customer ViewModel class 并创建一个 ObservableCollection<Customer> customers 会很容易并将其设置为数据网格的 ItemsSource 并使用它来绑定列。

public class Customer
{
    public string Name {get; set;}
    public string Location {get; set;}
}

ObservableCollection<Customer> customers = new ObservableCollection<Customer>();

使用 CustomerNamesList 和适当的 locationList

中的名称填充 customers 集合
foreach(var customer in CustomerNameList )
{ 
    string location = string.Empty;
    //ThirdList is your Dictionary<string, string>
    if(ThirdList.Contains(customerName)) // Get customer location
        location = ThirdList[customerName];
    customers.Add(new Customer{Name=cusotmerName, Location=location});
}

在 XAML 中创建一个名为 CustomerViewSourceCollectionViewSource 并将其绑定到数据网格的 ItemsSource

<UserControl.Resources>
    <CollectionViewSource x:Key="CustomerViewSource"/>
</UserControl.Resources>

在后面的代码中,将 CustomerViewSource.Source 设置为 ObservableCollection<Customer> customers

CollectionViewSource CustomerViewSource = this.Resources["CustomerViewSource"] as CollectionViewSource;
CustomerViewSource.Source = customer;

在XAML中,将DataGridTextColumn的绑定设置为customers集合的Name属性并设置ComboBox.SelectedItem' s 绑定到 Location

<DataGrid x:Name="CustomerLocationGrid" Height="265" VerticalAlignment="Center" Margin="-7,8,-2,-6" AutoGenerateColumns="False"
    ItemsSource="{Binding Source={StaticResource CustomerViewSource}, UpdateSourceTrigger=PropertyChanged}" > 
 <DataGrid.Columns>
     <DataGridTextColumn x:Name="customerDisplayList" Header="CustomerName" MinWidth="500" IsReadOnly="True"  Binding="{Binding Name}"/>
     <DataGridTemplateColumn x:Name="networkTypeTemplateColumn" Header="Location" MinWidth ="200" CanUserResize="True" Width="*">
           <DataGridTemplateColumn.CellTemplate>
                 <DataTemplate>
                     <ComboBox x:Name="locationCombobox"  ItemsSource="{Binding locationList, RelativeSource={RelativeSource AncestorType=UserControl}}" 
                        SelectedItem="{Binding Location}"/>
                 </DataTemplate>
            </DataGridTemplateColumn.CellTemplate>
     </DataGridTemplateColumn>
   </DataGrid.Columns>
</DataGrid>

现在,您的数据网格将显示所有预填充的客户信息,对于没有位置信息的客户,用户将能够select它,您可以在 customers 集合中检索它