【发布时间】:2016-08-28 13:11:38
【问题描述】:
我正在使用 C# Winforms 和实体框架,我的项目基于此链接: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.Data.Entity.Internal.DbLocalView`1[Project1.Contexts.table1]”类型的对象转换为“System.Data.DataTable”类型。
尝试在其他网站上搜索其他类似问题,但找不到将System.Data.Entity.Internal.DbLocalView 转换为DataTable 的方法。
编辑:
这是我的代码和要求。
要求:
我有 2 个表单,第一个表单有 DataGridView,名为 enrollmedsDataGridView,其 DataBounded 为 enrollmedsBindingSource。 enrollmedsBindingSource.DataSource 设置为 m3d.enrollmeds.Local(m3d 是我的上下文)。窗口有ItemRemarks 的文本框(每个选定项目的备注),Save 的按钮用于保存列表,Add 的按钮将打开第二个表单以选择项目主列表中的项目。
要将第二个表单中的选定项目转移到第一个表单,我将DataGridView 转换为DataTable 然后清除第一个表单的BindingSource 并将所选项目重新添加到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):
M3dEntities m3d = new M3dEntities();
private void EnrollMedSelectionFrm_Load(object sender, EventArgs e)
{
var items = from i in m3d.items
where i.ItemGroup == "Medicine"
select new
{
i.PK_Items,
i.ItemID,
i.ItemDesc,
i.GenericName
};
if (items != null)
{
DataTable dt = new DataTable();
foreach (DataGridViewColumn col in ItemSelectionDataGridView.Columns)
{
dt.Columns.Add(col.Name);
col.DataPropertyName = col.Name;
};
foreach (var element in items)
{
var row = dt.NewRow();
row["PK_Items"] = element.PK_Items;
row["ItemID"] = element.ItemID;
row["ItemDesc"] = element.ItemDesc;
row["GenericName"] = element.GenericName;
dt.Rows.Add(row);
}
ItemSelectionDataGridView.DataSource = dt;
}
}
private void SelectBtn_Click(object sender, EventArgs e)
{
EnrollMedicationFrm enrollfrm = (EnrollMedicationFrm)Application.OpenForms["EnrollMedicationFrm"];
DataTable dt = new DataTable();
dt = (DataTable)ItemSelectionDataGridView.DataSource;
DataRow[] result = dt.Select("SelectedChkBox = 1");
if (result.Count() < 1)
{
enrollfrm.SelectedItems = null;
}
else
{
enrollfrm.SelectedItems = result.CopyToDataTable();
}
this.DialogResult = DialogResult.OK;
}
我对这个流程进行了许多表单验证,但它们都有这个问题:( 一旦这个问题得到解决,我认为所有或大部分都可以解决
请指导我如何解决这个问题,其他方法甚至解决方法可能会有很大帮助,非常感谢提前:)
【问题讨论】:
-
DataGridView1中设置的数据源类型是什么?
-
实体框架table1的Bindingsource @Jackdaw
-
A
DataGridView是一个 visual 组件 - 不仅仅是数据 - 所以 cannot 可能被转换为DataTable(其中仅数据)。BindingSource也是如此 - 这是一个非可视组件,但同样:它比裸数据更多,因此您不能将其转换为DataTable。您需要做的是使用网格或绑定源的基础数据并将其转换/转换为DataTable- 或使用DataTable在第一个提供网格或绑定源地点! -
嗨@marc_s,我认为我的问题的基础数据是
System.Data.Entity.Internal.DbLocalView。但我找不到将DbLocalView转换为DataTable的方法。你能给我一个关于如何进行转换的示例或链接吗? -
如果您已经创建了
DataTable,那么只需将行添加到DataTable。如果您没有DataTable,请查看此post。但我很好奇您在使用 Entity Framewrok 时考虑到DataTable的实际要求。
标签: c# winforms entity-framework datagridview datatable