【问题标题】:Binding a Combobox control to a separate source within a DataGrid将 Combobox 控件绑定到 DataGrid 中的单独源
【发布时间】:2011-01-18 17:01:42
【问题描述】:

我试图在 DataGrid 中使用 ComboBox,这将允许用户选择来自不同表的值。我使用 ViewModel 类作为 DataContext,其中包含终端的 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 的一部分时,ComboBox 上的绑定行为显然是不同的,但我对为什么有点难过?

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

【问题讨论】:

  • 为什么不使用

标签: c# wpf binding


【解决方案1】:

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

您可以做的是在您的绑定中使用相对源。有了这个,您可以导航到 DataGrid 的 DataContext,然后访问您的 TerminalTypes-Collection:

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

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

【讨论】:

  • 我认为 OP 已经在使用 MVVM,因为他提到数据在 ViewModel 上:-)
  • 这行得通,我猜是 DataContext.TerminalTypes 和 RelativeSource 成功了。
  • 天哪,为什么这么复杂?我花了几个小时才找到一个真正有效的答案。谢谢!
  • 非常感谢,我尝试找到几个高于 DataGrid 的 RelativeSource,直到我找到你的答案,并尝试了 Datagrid。有效!!谢谢。
【解决方案2】:

您应该查看来自 Aran Mulholland 的 this answer

它有一个很好的使用DataGridComboBoxColumn的示例

为您的 XAML 改编 this article

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

</my:DataGridComboBoxColumn>

【讨论】:

  • 这看起来就像它应该工作,但它没有,我一定在这里遗漏了一些明显的东西。
【解决方案3】:

这是我在我的小测试项目中最终得到的结果,我将对其进行调整以用于正确的代码。

<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>

【讨论】:

    猜你喜欢
    • 2014-10-10
    • 1970-01-01
    • 2021-03-29
    • 1970-01-01
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-13
    相关资源
    最近更新 更多