我正在使用C#Winforms和Entity Framework,我的项目建模在此链接上:Databinding with WinForms
我的问题是如何将DataGridView
或BindingSource
转换为DataTable
?
我试过这段代码:
DataTable data = (DataTable)(DataGridView1.DataSource);
但是因错误而失败:
无法转换类型为#System; Windows.Forms.BindingSource'的对象输入' System.Data.DataTable'。
然后我尝试了这段代码:
BindingSource bs = (BindingSource)DataGridView1.DataSource;
DataTable dt = (DataTable)bs.DataSource;
但最终会出现另一个错误:
无法转换类型为#System; System.Data.Entity.Internal.DbLocalView`1 [Project1.Contexts.table1]'输入' System.Data.DataTable'。
尝试搜索其他类似问题和其他网站,但找不到将System.Data.Entity.Internal.DbLocalView
转换为DataTable
的方法。
修改
这是我的代码和要求。
要求:
我有2个表单,第1个表单的DataGridView
名为enrollmedsDataGridView
,DataBounded为enrollmedsBindingSource
。 enrollmedsBindingSource.DataSource
设置为m3d.enrollmeds.Local
(m3d
是我的上下文)。窗口包含ItemRemarks
的文本框(每个项目的备注选项),Save
按钮保存Add
的列表和按钮,这将打开第二个表单以选择项目物品主列表。
要将第二个表单上的所选项目转移到第一个表单,我将DataGridView
转换为DataTable
,然后清除第一个表单的BindingSource
并将所选项目重新添加到{ {1}}
我想要的是让第二种形式知道哪些项目已经被选中以便能够设置默认选择的项目(目前第二种形式默认是所有项目都未选中)
第一表格的代码 BindingSource
:
(EnrollMedicationFrm)
第二表格代码 M3dEntities m3d = new M3dEntities();
enrollmeds _enrollmeds;
EnrollMedSelectionFrm enrollselectfrm;
public DataTable SelectedItems { get; set; }
public string SelectedAdmNo { get; set; }
private void EnrollMedicationFrm_Load(object sender, EventArgs e)
{
var _SelectedPKAdm = (from p in m3d.admission
where p.admissionNo == SelectedAdmNo
select p.PK_Admission).FirstOrDefault();
int _selectedAdmno = int.Parse(SelectedAdmNo);
m3d.enrollmeds.Where(adm => adm.FK_Admission == _SelectedPKAdm).ToList();
this.enrollmedsBindingSource.DataSource = m3d.enrollmeds.Local;
}
private void AddBtn_Click(object sender, EventArgs e)
{
enrollselectfrm = new EnrollMedSelectionFrm();
var pxdetails = (from adm in m3d.admission
join pxDC in m3d.datacenter
on adm.FK_DC_Patient equals pxDC.PK_Datacenter
where adm.admissionNo == SelectedAdmNo
select new
{
adm,
pxDC
}).FirstOrDefault();
if (enrollselectfrm.ShowDialog() == DialogResult.OK)
{
if (SelectedItems == null)
{
enrollmedsBindingSource.Clear();
}
else
{
enrollmedsBindingSource.Clear();
foreach (DataRow dr in SelectedItems.Rows)
{
_enrollmeds = new enrollmeds();
_enrollmeds.FK_DC_Patient = pxdetails.pxDC.PK_Datacenter;
_enrollmeds.FK_DC_userAdd = mainfrm.PK_DC_UserLoggedIn;
var svrDT = ((IObjectContextAdapter)m3d).ObjectContext.CreateQuery<DateTime>("CurrentDateTime() ");
DateTime currdatetime = svrDT.AsEnumerable().First();
_enrollmeds.AddDateTime = currdatetime;
_enrollmeds.FK_Admission = pxdetails.adm.PK_Admission;
_enrollmeds.Qty = 0;
int pkItems = int.Parse(dr.Field<string>("PK_Items").ToString());
var itemdtls = (from i in m3d.items
where i.PK_Items == pkItems
select i).FirstOrDefault();
_enrollmeds.FK_Items = pkItems;
_enrollmeds.ItemRemarks = itemdtls.ItemRemarks;
enrollmedsBindingSource.Add(_enrollmeds);
}
}
}
}
:
(EnrollMedSelectionFrm)
我对此流程有很多表单验证,但所有这些都有此问题:( 一旦这个问题得到解决,我认为其中所有或大部分都可以修复
请指导我如何解决这个问题,其他方法甚至解决方法都可以提供很大的帮助,非常感谢提前:)
答案 0 :(得分:1)
使用实体框架时,您不需要使用DataTable
。相反,您应该依赖List<T>
,DbSet<T>
,ObservableCollection<T>
,BindingList<T>
等类。
让我们关注当前的要求:
我想要的是让第二种形式知道什么是物品 已经选定......
请考虑以下注意事项:
将DataGridView
绑定到List<T>
时,每行的DataBoundItem
属性的类型为T
。
Rows
DataGridView
个DataGridView
集合
由于您使用CheckBoxColumn1
检查某些行,因此您可以在网格中设置一个复选框列,并将其名称设置为private void selectButton_Click(object sender, EventArgs e)
{
this.dataGridView1.EndEdit();
var checkedItems = this.dataGridView1.Rows.Cast<DataGridViewRow>()
.Where(x => (bool?)x.Cells["CheckBoxColumn1"].Value == true)
.Select(x => x.DataBoundItem)
.Cast<MyItem>().ToList();
//use checkedItems
}
。然后在您的选择按钮中,您可以通过以下方式找到选中的项目:
MyItem
在上面的代码中,我认为match = []
是您在网格中显示的列表项的类型。