【问题标题】:WPF DataGrid / LINQ Query (DataGrid new row not visible)WPF DataGrid / LINQ 查询(DataGrid 新行不可见)
【发布时间】:2013-05-08 16:50:33
【问题描述】:

我对 WPF/LINQ2Entities 比较陌生。我设法取得了进展,但我一直在研究一个问题:

1) 我有一个基于此 CollectionViewSource 填充的 WPF DataGrid。 CollectionViewSource 的来源是一个 LINQ 查询。

    Private context As New QADBEntities        
    Dim QADBEntitiesViewSource As CollectionViewSource

    Dim SalesOrderSerialNumber_Query = From salesOrders In context.tblSalesOrders
                           Join serialNumbers In context.tblSerialNumbers
                           On salesOrders.Sales_Order_ID Equals serialNumbers.Sales_Order_ID
                           Where salesOrders.Sales_Order_ID = 5
                           Select New With {salesOrders, serialNumbers}


    QADBEntitiesViewSource = CType(Me.FindResource("QADBEntitiesViewSource"), CollectionViewSource)
    QADBEntitiesViewSource.Source = SalesOrderSerialNumber_Query.ToList()

以下是 DataGrid 的 XAML 的摘录:

            <DataGrid x:Name="TblSerialNumbersDataGrid" AutoGenerateColumns="False" EnableRowVirtualization="True" CanUserAddRows="True"
              ItemsSource="{Binding Source={StaticResource QADBEntitiesViewSource}}" Margin="293,44,10,16" 
              RowDetailsVisibilityMode="VisibleWhenSelected" Grid.ColumnSpan="2">
              <DataGrid.Columns>
                  <DataGridTextColumn x:Name="Kit_Group_IDColumn" Binding="{Binding serialNumbers.Kit_Group_ID}" Header="Kit Group ID" Width="SizeToHeader"/>
                  <DataGridTextColumn x:Name="NotesColumn" Binding="{Binding serialNumbers.Notes}" Header="Notes" Width="SizeToHeader"/>
                  <DataGridTextColumn x:Name="Product_IDColumn" Binding="{Binding serialNumbers.Product_ID}" Header="Product ID" Width="SizeToHeader"/>
                  <DataGridTextColumn x:Name="Production_Lead_IDColumn" Binding="{Binding serialNumbers.Production_Lead_ID}" Header="Production Lead ID" Width="SizeToHeader"/>
                  <DataGridTextColumn x:Name="QA_Personnel_IDColumn" Binding="{Binding serialNumbers.QA_Personnel_ID}" Header="QA Personnel ID" Width="SizeToHeader"/>
                  <DataGridTextColumn x:Name="Sales_Order_IDColumn" Binding="{Binding serialNumbers.Sales_Order_ID}" Header="Sales Order ID" Width="SizeToHeader"/>
                ....etc
              </DataGrid.Columns>
    </DataGrid>

2) 问题:填充 DataGrid 并对数据进行更改工作正常。但是,DataGrid 未在网格底部显示新行以添加其他记录

我相信它与 LINQ 查询有关,因为当我以这种方式填充 DataGrid 时:

            QADBEntitiesViewSource = CType(Me.FindResource("QADBEntitiesViewSource"), CollectionViewSource)
            QADBEntitiesViewSource.Source = context.SalesOrderListSQ.ToList()

....一切,包括新行,都可以正常工作。任何帮助或指示将不胜感激。再次,我对此很陌生,我意识到这可能是我整个设计的问题。谢谢。

【问题讨论】:

  • 只是猜测:也许问题在于CollectionViewSource 是只读的。作为快速测试,我会尝试使用ObservableCollection 或类似的源代码。

标签: wpf vb.net linq


【解决方案1】:

实际上,这里的问题不在于 LINQtoEntities,也不在于 Grid,而在于 EF。 EF 支持对集合中的对象进行更改,甚至在您向表中添加行(即向 ObjectSet 中添加项)时甚至会更改通知,但不支持通过 CollectionViewSource 自动添加行。如果需要,您可以返回到 DataSet,或者只是创建一个“添加新”命令,将新项目添加到 ObjectSet 并使其成为 CollectionViewSource 的当前项目。

调用CollectionViewSource.View.Refresh可以刷新CollectionViewSource,调用CollectionViewSource.View.MoveCurrentTo(newItem)可以使某个item成为当前item。但是,在您的对象查询的情况下,您可能需要再次运行查询,即重复 CollectionViewSource.Source = ...

我发现 EF 对集合视图源的支持不稳定;这在很大程度上取决于您如何准确地获得实体列表,哪些是受支持的,哪些是不支持的。您的第一个代码返回一个 ObjectQuery,它必须再次执行才能识别对基础列表的更改,而第二个示例返回一个 ObjectSet,据我所知,它支持添加和删除项目以及集合更改通知。所以,实际上我应该在第一段中说 EF 仅在某些情况下支持通过 CollectionViewSource 添加行...

【讨论】:

  • 我发现你所说的 add new 命令是什么意思,它工作得很好。现在我只需要了解如何刷新表格或“使其成为 CollectionViewSource 的当前项目”,如您所说。我真的不想去数据集,因为我认为 LINQtoEntities 是要走的路。谢谢您的帮助。但我仍然不确定我是否理解为什么在另一个 DataGrid 上(参见最后一个代码 sn-p)我能够使用 EF 和数据绑定通过新行添加新记录。我是不是误会了?
  • hbarck -- 这回答了我的大部分问题。非常感谢您的帮助。
  • 此外,如果您有时间,这只是一个需要回答的外围问题:您对使用 DataGrids 和 LINQtoEntities 查询进行数据操作的最佳/有效途径有什么建议吗?我意识到有不止一种方法可以做到这一点,但是否有一种大多数人似乎认为有效的标准做法?我发现使用 CollectionViewSource 有效,但我不知道从长远来看,使用多个表/连接查询是否最好。
  • 抱歉,对最好的方法一无所知...到目前为止(.net 4.0),我既不喜欢 EF 也不喜欢 DataGrid...
【解决方案2】:

Linq 查询结果是只读的,如果您希望能够将项目添加到数据源中,您可能需要提供自己的类作为 Source,它会枚举您的结果 (IEnumerable),并且还提供方法操作数据源 (IList)。

【讨论】:

  • H.B. - 非常感激。我不知道 Linq 查询结果。因此,即使 linq 查询结果是只读的,也可以保存对数据的更改(我可以这样做)?
  • @K.Akins:集合本身与它的项目不同,任何可变的对象仍然是可变的,即使它是不可变集合的一部分(如 IEnumerables 返回的Linq 查询)。
猜你喜欢
  • 2010-12-07
  • 1970-01-01
  • 2010-10-14
  • 1970-01-01
  • 2011-02-27
  • 2014-10-30
  • 2012-03-25
  • 1970-01-01
  • 2011-02-18
相关资源
最近更新 更多