【问题标题】:Bind to Combobox in Datagrid绑定到 Datagrid 中的 Combobox
【发布时间】:2021-03-29 05:18:54
【问题描述】:

我想创建一个 Datagrid,如下所示: DatagridDesign

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

由于我是 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 MainWindow

Sub New()
InitializeComponent()

DataContext = New Employee()
End Sub

结束类

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 不起作用))。有什么概念清晰的帖子或网站吗?我浏览了很多示例和帖子,但每个人都有不同的方法,有时我会迷失方向!

【问题讨论】:

    标签: wpf vb.net xaml binding datagrid


    【解决方案1】:

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

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

    所以不是单项:

    DataContext = New Employee()
    

    你仍然必须使用集合:

    Class MainWindow
        Dim appRow As New ObservableCollection(Of Employee)
    
        Sub New()
        InitializeComponent()
    
        appRow.Add(New Employee())
        
        DataContext = appRow
        End Sub
    End Class
    

    但初始化发生在 Employee 类中


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

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

    xaml 的变化:

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

    【讨论】:

    • 非常感谢。这暂时有效。但是是否可以直接将 Datagrid 与 Class 绑定?也许 ItemsSource="{Binding Employee}"?所以我也可以跳过这部分,得到我最初要求的相同吗?
    • 不,这是不可能的。正如我所说,ItemsSource 应该是某种序列(IEnumerable)。如果您想使用单个项目,则可以使用 3 个单独的组合框而不使用 DataGrid
    • 您可以将项目添加到项目集合中而无需绑定
    猜你喜欢
    • 1970-01-01
    • 2014-10-10
    • 1970-01-01
    • 2020-07-20
    • 1970-01-01
    • 2013-03-22
    • 2014-09-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多