C# 将Combobox控件绑定到DataGrid中的单独源

C# 将Combobox控件绑定到DataGrid中的单独源,c#,wpf,binding,C#,Wpf,Binding,我试图在DataGrid中使用一个组合框,它允许用户从不同的表中选择一个值。Im使用ViewModel类作为DataContext,其中包含一个用于终端的ObservableCollection和另一个用于终端类型的ObservableCollection 网格上的绑定很好,所有的行都被填充,DataGridTextColumns都显示了正确的数据,但是我的ComboBox是空的 我知道我试图绑定到的ObservableCollection已经被填充,如果我将ComboBox移到DataGrid

我试图在DataGrid中使用一个组合框,它允许用户从不同的表中选择一个值。Im使用ViewModel类作为DataContext,其中包含一个用于终端的ObservableCollection和另一个用于终端类型的ObservableCollection

网格上的绑定很好,所有的行都被填充,DataGridTextColumns都显示了正确的数据,但是我的ComboBox是空的

我知道我试图绑定到的ObservableCollection已经被填充,如果我将ComboBox移到DataGrid之外,它将按预期工作

<my:DataGrid Name="MenuDetailGrid" AutoGenerateColumns="False" ItemsSource="{Binding Terminals}">
    <my:DataGrid.Columns>
        <my:DataGridTextColumn Header="Terminal Type ID" Binding="{Binding TERMINAL_TYPE_ID}" IsReadOnly="True" />
        <my:DataGridTemplateColumn Header="Terminal Type">
            <my:DataGridTemplateColumn.CellTemplate>
                <DataTemplate>
                    <ComboBox DisplayMemberPath="TTYPE_NAME" SelectedValuePath="TERMINAL_TYPE"
                              SelectedValue="{Binding TERMINAL_TYPE_ID}" 
                              ItemsSource="{Binding TerminalTypes}" />

                </DataTemplate>
            </my:DataGridTemplateColumn.CellTemplate>
        </my:DataGridTemplateColumn>

显然,当组合框是DataGrid的一部分时,绑定行为在组合框上是不同的,但我有点不明白为什么

有人能帮我理解我做错了什么吗?

你应该看看Aran Mulholland的文章

它有一个很好的示例,用于使用

适合您的XAML

<my:DataGridComboBoxColumn SelectedValueBinding="{Binding TERMINAL_TYPE_ID}"
  SelectedValuePath="TERMINAL_TYPE_ID"
  DisplayMemberPath="TERMINAL_TYPE"
  Header="Terminal Type"
  ItemsSource="{Binding TerminalTypes}" />

</my:DataGridComboBoxColumn>

绑定行为是相同的。但是,ItemsControl将DataTemplate中的DataContext设置为当前项,在您的情况下,这是
终端
-集合的成员。因此,无法找到TerminalTypes集合(除非您也在项目上实现它)

您可以做的是在绑定中使用相对源。通过此操作,您可以导航到DataGrid的DataContext,然后访问您的
终端类型
-集合:

<ComboBox DisplayMemberPath="TTYPE_NAME"
    SelectedValuePath="TERMINAL_TYPE"
    SelectedValue="{Binding TERMINAL_TYPE_ID}"
    ItemsSource="{Binding DataContext.TerminalTypes,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=DataGrid}" /> 


希望这有帮助。如果没有,请发表评论。

这就是我在我的小测试项目中得到的结果,我将对其进行修改,以便在适当的代码中使用

<Grid>
    <Controls:DataGrid Name="MenuDetailGrid" AutoGenerateColumns="False" ItemsSource="{Binding Terminals}">
        <Controls:DataGrid.Columns>
            <Controls:DataGridTemplateColumn Header="SomeHeader">
                <Controls:DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding TTYPE_NAME}" />
                    </DataTemplate>
                </Controls:DataGridTemplateColumn.CellTemplate>
                <Controls:DataGridTemplateColumn.CellEditingTemplate>
                    <DataTemplate>
                        <ComboBox DisplayMemberPath="TTYPE_NAME"
                            SelectedValuePath="TERMINAL_TYPE_ID"
                            SelectedValue="{Binding TERMINAL_TYPE_ID}"
                            ItemsSource="{Binding DataContext.TerminalTypes,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Controls:DataGrid}}" />
                    </DataTemplate>
                </Controls:DataGridTemplateColumn.CellEditingTemplate>
            </Controls:DataGridTemplateColumn>
        </Controls:DataGrid.Columns>
    </Controls:DataGrid>
</Grid>


为什么不使用?这看起来很像它应该可以工作,但它没有,我肯定错过了一些明显的东西。我认为OP已经在使用MVVM了,因为他提到数据在ViewModel上:-)这很有效,我猜是DataContext.TerminalTypes和RelativeSource起了作用。天哪,为什么这么复杂?我花了几个小时才找到一个真正有效的答案。谢谢非常感谢,我试着找到了几个比DataGrid更高的相对资源,直到我找到了你的答案,并尝试了DataGrid。成功了!!非常感谢。