绑定到数据网格中的组合框

Bind to Combobox in Datagrid

我想创建一个数据网格,如下所示: DatagridDesign

解释一下:我想要一个带有一些组合框(类型、数量、单元格)的数据网格,其中没有任何 selected 但包含项目。为简单起见,假设 Header(类型:将具有 type1、type2、type3 的选项)、(数量:1、2、3)、(单元格:cell1、cell2、cell3)。我希望用户从组合框中 select ,当“添加行”将给出包含项目的另一行时,等等。最后我想把它们保存到数据库中。

由于我是 WPF 和绑定概念的新手,我尝试了如下操作:

我的VB.Net代码:

Imports System.Collections.ObjectModel

Class MainWindow
    Dim appRow As New ObservableCollection(Of Employee)

    Sub New()
    InitializeComponent()
    appRow.Add(New Employee With {.Cell = New ObservableCollection(Of String)({"cell1", "cell2", "cell3"}), .Type = New ObservableCollection(Of String)({"type1", "type2", "type3"})})
    appRow.Add(New Employee With {.Cell = New ObservableCollection(Of String)({"cell1", "cell2", "cell3"}), .Type = New ObservableCollection(Of String)({"type1", "type2", "type3"})})
    
    DataContext = appRow
    End Sub
End Class

Public Class Employee
    Dim _Type As New ObservableCollection(Of String)
    Dim _Cell As New ObservableCollection(Of String)

    Public Property Type() As ObservableCollection(Of String)
        Get
            Return _Type
        End Get
        Set(ByVal value As ObservableCollection(Of String))
            _Type = value
        End Set
    End Property

    Public Property Cell() As ObservableCollection(Of String)
        Get
            Return _Cell
        End Get
        Set(ByVal value As ObservableCollection(Of String))
            _Cell = value
        End Set
    End Property
End Class

还有我的Xaml代码:

<Window x:Class="MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:Testing"
    mc:Ignorable="d"
    Title="MainWindow" Height="450" Width="800">

    <Grid>
    <DataGrid Margin="5" ItemsSource="{Binding}" AutoGenerateColumns="False">
        <DataGrid.Columns>
            <DataGridTemplateColumn Header="Type" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Margin="2" ItemsSource="{Binding Type}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

            <DataGridTemplateColumn Header="Quantity" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Margin="2">
                            <ComboBoxItem Content="1" />
                            <ComboBoxItem Content="2" />
                            <ComboBoxItem Content="3" />
                        </ComboBox>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            
            <DataGridTemplateColumn Header="Cell" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <ComboBox Margin="2" ItemsSource="{Binding Cell}"/>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
        </DataGrid.Columns>
    </DataGrid>

    </Grid>

现在,这是有效的。但是我想在 class 本身中设置项目,所以当它被调用时它会用值初始化。所以我尝试了:

Class MainWindow

Sub New()
InitializeComponent()

DataContext = New Employee()
End Sub

结束Class

Public Class Employee
    (Same as before...)
    Sub New()
        Cell = New ObservableCollection(Of String)({"cell1", "cell2", "cell3"})
        Type = New ObservableCollection(Of String)({"type1", "type2", "type3"})
    End Sub
End Class

和Xaml保持不变。与我将普通组合框绑定到我的 WPF 的方式相同,并且可以正常工作。但是对于 Datagrid,它不是。它也没有显示任何错误并正常运行。

有谁知道我哪里做错了吗?或者我怎样才能得到我想要得到的结果? 最近几天我真的被困在这里了!非常感谢您的帮助和付出!

旁注:为什么 Datagrid 中的绑定如此复杂!知道在哪里可以获得完整的概述吗?例如(我仍然很困惑为什么 Datacontext、itemsource、ObservableCollection(为什么 list of list of string 不起作用))。有什么概念清楚的post或者网站吗?我经历了很多例子和 posts,但每个人的方法都不一样,有时我会迷路!

ItemsSource 应该是某种序列 (IEnumerable)。

由于您直接绑定 DataContext,DataContext 应该是 IEnumerable

所以不是单个项目:

DataContext = New Employee()

你还得用collection:

Class MainWindow
    Dim appRow As New ObservableCollection(Of Employee)

    Sub New()
    InitializeComponent()

    appRow.Add(New Employee())
    
    DataContext = appRow
    End Sub
End Class

但初始化发生在 Employee 内部 class


或者您可以在不绑定的情况下将项目添加到项目集合中:

Sub New()
    InitializeComponent()

    MyDataGrid.Items.Add(New Employee())
End Sub

xaml 的变化:

<DataGrid Name="MyDataGrid" AutoGenerateColumns="False">