【问题标题】:WPF Datagrid generates rows, but the columns stay blankWPF Datagrid 生成行,但列保持空白
【发布时间】:2012-12-22 14:07:09
【问题描述】:

我正在尝试在 WPF 中填充数据网格,就像在 Silverlight 中填充它一样,但显然它的工作方式并不相同。

这是 XAML 中的网格:

 <DataGrid x:Name="gvEintraege"
                            CanUserAddRows="False"
                            CanUserDeleteRows="False"
                  IsReadOnly="True"
                  AutoGenerateColumns="True" >
            <DataGrid.Columns>
                <DataGridTextColumn Header="Datum"
                                    Width="100"
                                Binding="{Binding datum}"/>
                <DataGridTextColumn Header="Gewicht"
                                    Width="70"
                                Binding="{Binding gewicht}"/>
                <DataGridTextColumn Header="Muskelmasse"
                                    Width="80"
                                Binding="{Binding muskelmasse}"/>
                <DataGridTextColumn Header="Fettmasse"
                                    Width="70"
                                Binding="{Binding fettmasse}"/>
                <DataGridTextColumn Header="BMI"
                                    Width="40"
                                Binding="{Binding bmi}"/>
                <DataGridTextColumn Header="FFMI"
                                    Width="50"
                                Binding="{Binding ffmi}"/>
                <DataGridTextColumn Header="KFA"
                                    Width="50"
                                Binding="{Binding kfa}"/>
            </DataGrid.Columns></DataGrid>

这是整个代码隐藏:

Public Class LogWindow

Dim gvEintraege_Itemssource As New ObservableCollection(Of clsGridEintrag)
Public globaleVariablen As Application

Public Sub New()

    InitializeComponent()

    Me.globaleVariablen = Application.Current

    Me.getLogEintraege()

    Me.gvEintraege.ItemsSource = Me.gvEintraege_Itemssource
End Sub

Private Sub getLogEintraege()
    Try
        Dim myLog As clsLog = clsSerializer.DeSerialize(Me.globaleVariablen.standardPfadLogs & "\" & Me.globaleVariablen.aktiverUser & ".xml", New clsLog)
        With myLog
            For Each x In .eintraege
                Me.gvEintraege_Itemssource.Add(New clsGridEintrag(x.datum, x.gewicht, x.kfa, x.muskelmasse, x.fettmasse, x.ffmi, x.bmi))
            Next
        End With
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub


Public Class clsGridEintrag
    Public datum As Date
    Public gewicht As Decimal
    Public kfa As Decimal
    Public muskelmasse As Decimal
    Public fettmasse As Decimal
    Public ffmi As Decimal
    Public bmi As Decimal

    Public Sub New()

    End Sub

    Public Sub New(datum_ As Date, gewicht_ As Decimal, kfa_ As Decimal, muskelmasse_ As Decimal, fettmasse_ As Decimal, ffmi_ As Decimal, bmi_ As Decimal)
        Me.bmi = bmi_
        Me.datum = datum_
        Me.fettmasse = fettmasse_
        Me.ffmi = ffmi_
        Me.gewicht = gewicht_
        Me.kfa = kfa_
        Me.muskelmasse = muskelmasse_
    End Sub
End Class

结束类

网格为 itemssource 中的每个项目创建一行,但不显示列中的任何数据。看起来它应该以这种方式工作,但显然我在某个地方犯了一个错误。我正在为此烦恼,因为它看起来很容易,但它不起作用。

【问题讨论】:

    标签: wpf vb.net wpfdatagrid


    【解决方案1】:

    我认为您没有看到任何内容,因为您没有使用公共属性或依赖项属性。绑定仅适用于其中 2 个。由于您尝试绑定到公共变量,因此它将不起作用。我很确定调试输出也会警告您找不到绑定。

    否则,将“自动生成列”设置为 true,您不必指定列。网格应该能够读取您的对象(将其绑定到包含您的自定义对象的 observablecollection)并为每个公共依赖属性或公共属性生成一列(这意味着它们具有 get/set 访问器)。

    下一个答案也是对的,你忘了设置数据上下文;)

    1. 确保已设置 DataContext。
    2. 在窗口/控件类中创建一个 ObservableCollection 作为公共属性:Public Property myCollection As New ObservableCollection&lt;clsGridEintrag&gt;()
    3. 将您的 clsGridEintrag 变量更改为“公共属性”,类似于 observablecollection。
    4. 将 DataGrid 的 ItemsSource 绑定到 myCollection
    5. 通过一个接一个地添加 clsGridEintrag 对象来填充 ObservableCollection(使用 myCollection.Add(myObject))。

    我不在我的编码计算机上,但如果您使用 AutogenerateColumns = true,以上内容应该会给您想要的结果。 DataGrid 将在您的 clsEntraig 对象中的每个公共属性的名称之后命名每个标题,并且应该正确列出它们。

    Here's some additional information,记住“客户”可能是一个包含“客户”对象的 ObservableCollection。在“客户”对象中,我们希望在 DataGrid 中看到的变量很可能被设置为“公共属性”(在 C# 中,等价物类似于 public string myString {get; set;} - 如果您看到 get/set,它是一个属性)。祝你好运!

    【讨论】:

    • 我现在设置了 Datacontext 并将 gvEintraege_Itemssource 更改为 Public。到目前为止,一切都没有改变。您对调试器中的错误是正确的,但我不知道接下来需要做什么。
    • 正如我所说,您只能绑定到依赖属性和公共属性。公共属性与公共变量不同,因为它具有 Get 和 Set 访问器。我将在我的答案中添加一些步骤。
    • 哦,当您更改其中一个 clsGridEntr 对象中的值时,不要期望数据网格会自行更新,除非您在其上实现 INotifyPropertyChanged。但是,如果您从 myCollection 添加/删除对象,数据网格将添加/删除行,因为它是 ObservableCollection(并提供必要的通知)
    【解决方案2】:

    您尚未设置 DataContext 属性,因此您的绑定不起作用...

    LogWindow 中:

    Public Sub New()
    
      Me.DataContext = Me.gvEintraege ' or wherever your data is 
      InitializeComponent()
      ....
    End Sub
    

    【讨论】: