【问题标题】:(WPF MVVM) Autocreate columns in datagrid binding an ObservableCollection(of ...) including a Dictionary(of string,string)(WPF MVVM)在数据网格中自动创建列绑定 ObservableCollection(of ...),包括 Dictionary(of string,string)
【发布时间】:2021-04-07 14:54:58
【问题描述】:

解释一下我的 WPF 应用程序的背景:

在我的数据库中,我有三个表:文档、文档类型、元数据
每个文档都有一个文档类型。 Doctype 具有用户输入的元数据。

例如: 我有两种文档类型:InvoiceMail。 如果用户添加了一个文档,他需要选择其中一种文档类型。

如果用户选择Invoice,则要求他输入InvoiceNumberAmount 作为元数据。 如果用户选择Mail,则会要求他提供SenderSubject 作为元数据。

在 WPF 应用程序中,我有一个数据网格,应该显示所有文档和相关数据。对于每个元数据,应自动创建一列。

对于我的示例,这意味着我想要创建一个包含以下列的数据网格:
docname|doctype|InvoiceNumber|Amount|Sender|Subject

此值例如:
doc1|发票|IN1234|10.00| |
doc2|邮件| | |汤姆|测试邮件

由于缺少文档类型的元数据而导致的空值应该在数据网格中留空。

我有以下代码来创建示例数据并将其绑定到我的数据网格:

Class MainWindow

  Private Sub MainWindow_Loaded(sender As Object, e As RoutedEventArgs) Handles Me.Loaded
        Dim lst As New ObservableCollection(Of doc)

        'Example doctypes
        Dim DoctypeExampleInvoice As New Dictionary(Of String, String)
        DoctypeExampleInvoice.Add("InvoiceNumber", "IN1234")
        DoctypeExampleInvoice.Add("InvoiceAmount", "10.00")

        Dim DoctypeExampleMail As New Dictionary(Of String, String)
        DoctypeExampleMail.Add("Sender", "Tom")
        DoctypeExampleMail.Add("Subject", "Testmail")

        'Example docs
        Dim _doc As New doc With {.docname = "doc1", .doctype = "Invoice", .metadata = DoctypeExampleInvoice}
        lst.Add(_doc)

        Dim _doc2 As New doc With {.docname = "doc2", .doctype = "Mail", .metadata = DoctypeExampleMail}
        lst.Add(_doc2)

        dgv.ItemsSource = lst
    End Sub
End Class

Public Class doc
    Property docname As String
    Property doctype As String
    Property metadata As New Dictionary(Of String, String)
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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <DataGrid x:Name="dgv" ItemsSource="{Binding lst}" SelectionMode="Single" SelectionUnit="FullRow" AutoGenerateColumns="True"/>
    </Grid>
</Window>

这就是我的实际结果:

如您所见,元数据未显示为列,而是显示为包含集合的一列。如何完成这项工作?

提前致谢, 马可

【问题讨论】:

  • 在您的doc 类中,您应该创建映射到您的metadata 列表的key1key2key3 属性。
  • 嗨,艾蒂安,你是对的。我需要问不同的。我将重写我的问题以更好地解释我的问题。

标签: wpf vb.net


【解决方案1】:

doc 类的这些修改将允许您在网格中显示键 1-3:

Public Class doc

    Public Property docname As String
    Public Property doctype As String
    Public Property metadata As New Dictionary(Of String, String)

    ''' <summary>
    ''' Gets 'key1' from <see cref="metadata"/>
    ''' </summary>
    Public ReadOnly Property Key1 As String
        Get
            Return GetKey(0)
        End Get
    End Property

    ''' <summary>
    ''' Gets 'key3' from <see cref="metadata"/>
    ''' </summary>
    Public ReadOnly Property Key2 As String
        Get
            Return GetKey(1)
        End Get
    End Property

    ''' <summary>
    ''' Gets 'key3' from <see cref="metadata"/>
    ''' </summary>
    Public ReadOnly Property Key3 As String
        Get
            Return GetKey(2)
        End Get
    End Property

    ''' <summary>
    ''' Gets an item from <see cref="metadata"/> using 'key' + index.
    ''' </summary>
    ''' <param name="keyIndex"></param>
    Private Function GetKey(keyIndex As Integer) As String
        If metadata.Count > keyIndex Then
            Return metadata.ElementAt(keyIndex).Value
        Else
            Return "N/A"
        End If
    End Function

End Class

绑定到索引属性是可能的,您可以查看它,但这应该可以让您更进一步地显示您想要的内容。如果 sin metadata 的值发生变化,您还应该考虑在该类上实现 INotifyPropertyChanged

【讨论】:

    【解决方案2】:

    我已经使用可绑定的动态字典解决了这个问题。 详细信息可以在这里找到: Binding DataGrid to ObservableCollection<Dictionary>

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多