C# 如何对绑定到EF EntityCollection的WinForms DataGridView排序<;T>;
我正在尝试从EntityFramework4对象将WinForms DataGridView绑定到C# 如何对绑定到EF EntityCollection的WinForms DataGridView排序<;T>;,c#,winforms,entity-framework-4,datagridview,entitycollection,C#,Winforms,Entity Framework 4,Datagridview,Entitycollection,我正在尝试从EntityFramework4对象将WinForms DataGridView绑定到EntityCollection。问题是,我不知道如何(自动)排序 我所做的只是将BindingSource的DataSource属性设置为实体的集合 MyBindingSource.DataSource=CurrentItem.InvoiceNotes 我真的希望有一个简单的配置,我可以添加到这个工作;我真的不想将我的EF集合包装在一个新的BindingList容器中。要支持排序,源代码需要在启用
EntityCollection
。问题是,我不知道如何(自动)排序
我所做的只是将BindingSource的DataSource属性设置为实体的集合
MyBindingSource.DataSource=CurrentItem.InvoiceNotes代码>
我真的希望有一个简单的配置,我可以添加到这个工作;我真的不想将我的EF集合包装在一个新的BindingList容器中。要支持排序,源代码需要在启用排序的情况下实现IBindingList
。令人烦恼的是,AFAIK唯一的内置类型是DataView
然而,一切都没有失去;您最好的选择是创建数据的BindingList
,或者更确切地说,是internet上可用的众多BindingList
子类之一BindingList
提供了90%的排序支持—它只需要实现3个(IIRC)附加方法即可获得基本(一列)排序支持
Dinesh Chandnani在2005年()写了一系列文章,通过BindingSource很好地解释了绑定。它是在EF之前写的,但它提供了一些很好的背景信息。这里有一个小道消息:
当然,您可以将DataGridView直接绑定到DataTable并
绕过BindingSource,但BindingSource具有某些优势:
- 它公开属性来对列表进行排序、过滤列表等,这在其他方面是一件很痛苦的事情。(即,如果您将
DataGridView直接访问DataTable,然后对所需的DataTable进行排序
需要知道DataTable是一个IListSource,它知道
作为DataView和DataView的基础列表可以排序,
过滤等)
- 如果您必须设置主/子视图,那么BindingSource在这方面做得很好(更多详细信息请参阅我之前的文章)
- 对DataTable的更改是隐藏的(也在我上一篇文章中)
除了@Marc Gravell的答案之外,还有,所以你可以使用它,只需对EF集合、IQueryables、IEnumerables等调用.ToList()
。现在的问题是,如果你使用.ToList()
和排序,数据绑定还能工作吗?在我所有的测试中,(令我惊讶的是)答案是是(我在DGV和数据之间使用BindingSource
)
以下是LINQPad的片段和演示的屏幕截图:
// http://www.csharpbydesign.com/2009/07/linqbugging---using-linqpad-for-winforms-testing.html
void Main()
{
var context = this;
using (var form = new Form())
{
var dgv = new DataGridView();
var binder = new BindingSource();
// All of the following variations work
// var efCollection = context.NOS_MDT_PROJECT;
// var sortableCollection = new BindingListView<NOS_MDT_PROJECT>(
// efCollection.ToList());
// var efCollection = context.NOS_MDT_PROJECT.First()
// .NOS_DEFL_TEST_SECT;
// var sortableCollection = new BindingListView<NOS_DEFL_TEST_SECT>(
// efCollection.ToList());
var efCollection =
from p in context.NOS_MDT_PROJECT
where p.NMP_ID==365
from s in p.NOS_GPR_TST_SECT_COMN_DATA
from l in s.NOS_GPR_TST_LOC_DATA
select l;
var sortableCollection = new BindingListView<NOS_GPR_TST_LOC_DATA>(
efCollection.ToList());
binder.DataSource = sortableCollection;
dgv.DataSource = binder;
dgv.Dock = DockStyle.Fill;
form.Controls.Add(dgv);
form.Shown += (o, e) => {
dgv.AutoResizeColumns(DataGridViewAutoSizeColumnsMode.AllCells);
};
form.ShowInTaskbar=true;
form.ShowDialog();
if (context.IsDirty()) // Extension method
{
if (DialogResult.Yes == MessageBox.Show("Save changes?", "",
MessageBoxButtons.YesNo, MessageBoxIcon.Question, MessageBoxDefaultButton.Button2))
{
context.SaveChanges();
}
}
}
}
谢谢安德鲁·戴维
下面是Vb.net中BindingListView(BLV)的一个简单用法:
Imports Equin.ApplicationFramework
Dim elements As List(Of projectDAL.Document) = db.Document.Where(
Function(w)w.IdProject = _activeProject.Id).OrderBy(Function(i) i.Description).ToList
Dim mySource As BindingListView(Of projectDAL.Document)
mySource = New BindingListView(Of projectDAL.Document)(elements)
EntityCollection
继承IListSource还是BindingList?如果没有,则应该编写DataSource.Changed事件调用的自动排序例程。Googlenet上提供了大量排序例程…:)它确实支持IListSource,但不支持BindingList。既然它实现了IListSource,我能做些什么来启用排序吗?真是令人烦恼。我已经有了一个BindingList实现,但是这个网格应该支持添加和删除项,所以我想直接访问EntityCollection。哦,我只需要向EntityCollection和BindingList添加新项;我不得不做更糟糕的事情。我通常创建一个通过公共getter访问的内部绑定列表。注意:我通常不使用可编辑的数据网格。
Imports Equin.ApplicationFramework
Dim elements As List(Of projectDAL.Document) = db.Document.Where(
Function(w)w.IdProject = _activeProject.Id).OrderBy(Function(i) i.Description).ToList
Dim mySource As BindingListView(Of projectDAL.Document)
mySource = New BindingListView(Of projectDAL.Document)(elements)