我正在使用 C# Winforms 和 Entity Framework,我的项目是基于此链接建模的:Databinding with WinForms
我的问题是如何将 DataGridView
或 BindingSource
转换为 DataTable
?
我试过这段代码:
DataTable data = (DataTable)(DataGridView1.DataSource);
但是失败并出现错误:
Unable to cast object of type 'System.Windows.Forms.BindingSource' to type 'System.Data.DataTable'.
然后我尝试了这段代码:
BindingSource bs = (BindingSource)DataGridView1.DataSource;
DataTable dt = (DataTable)bs.DataSource;
但这以另一个错误结束:
Unable to cast object of type 'System.Data.Entity.Internal.DbLocalView`1[Project1.Contexts.table1]' to type 'System.Data.DataTable'.
尝试在其他网站上搜索其他类似问题,但找不到将 System.Data.Entity.Internal.DbLocalView
转换为 DataTable
的方法。
编辑:
这是我的代码和要求。
要求:
我有 2 个表单,第一个表单有名为 enrollmedsDataGridView
的 DataGridView
,它的数据绑定(bind)到 enrollmedsBindingSource
。 enrollmedsBindingSource.DataSource
设置为 m3d.enrollmeds.Local
(m3d
是我的上下文)。窗口有用于 ItemRemarks
的文本框(每个选定项目的备注)、用于保存列表的用于 Save
的按钮和用于用于打开 Add
的按钮在 Item Masterlist 中选择项目的第二种形式。
为了将第二个表单上的选定项目转移到第一个表单,我将 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);
}
}
}
}
第 2 表格的代码 (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;
}
我在这个流程中有很多表单验证,但它们都有这个问题:( 一旦这个问题得到解决,我认为所有或大部分问题也可以得到解决
请指导我如何解决这个问题,其他方法甚至变通方法可能会有很大帮助,在此先感谢您:)
最佳答案
使用 Entity Framework 时,您不需要使用 DataTable
.相反,你应该依赖像 List<T>
这样的类, DbSet<T>
, ObservableCollection<T>
, BindingList<T>
等等。
让我们关注当前需求:
What I want is to have a way for the 2nd form to know what items are already selected...
考虑这些注意事项:
当你绑定(bind)一个
DataGridView
到List<T>
,DataBoundItem
每行的属性类型为T
.您可以搜索
Rows
收藏DataGridView
调用Cast<DataGridViewRow>
由于您使用的是 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
是您在网格中显示的列表项类型。
关于C# Winform( Entity Framework )- 将数据绑定(bind) DataGridView 或 BindingSource 转换为 DataTable,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39191624/