Je travaille avec C # Winforms et Entity Framework, mon projet est modelé sur ce lien: Liaison de données avec WinForms
Ma question est comment puis-je convertir un DataGridView
ou un BindingSource
à un DataTable
?
J’ai essayé ce code:
DataTable data = (DataTable)(DataGridView1.DataSource);
mais cela a échoué avec une erreur:
Impossible de convertir l’object de type ‘System.Windows.Forms.BindingSource’ en ‘System.Data.DataTable’.
Ensuite, j’ai essayé le code suivant:
BindingSource bs = (BindingSource)DataGridView1.DataSource; DataTable dt = (DataTable)bs.DataSource;
mais cela aboutit à une autre erreur:
Impossible de transtyper l’object de type ‘System.Data.Entity.Internal.DbLocalView`1 [Project1.Contexts.table1]’ vers le type ‘System.Data.DataTable’.
J’ai essayé de chercher d’autres questions similaires et sur d’autres sites, mais je ne peux pas trouver un moyen de convertir System.Data.Entity.Internal.DbLocalView
en DataTable
.
Modifier:
Voici mon code et mes exigences.
Exigences:
J’ai 2 formes, la 1ère forme a DataGridView
nommé enrollmedsDataGridView
qui DataBounded à inscriremedsBindingSource. m3d.enrollmeds.Local
est défini sur m3d.enrollmeds.Local
( m3d
est mon contexte). La fenêtre contient une zone de texte pour ItemRemarks
(remarques par article sélectionné), un bouton pour Save
pour enregistrer la liste et un bouton pour Add
qui ouvrira le deuxième formulaire pour la sélection des éléments de la liste des éléments.
Pour transférer les éléments sélectionnés du deuxième formulaire au premier formulaire, je BindingSource
DataGridView
en DataTable
puis BindingSource
le BindingSource
du premier formulaire et ré-ajoute les éléments sélectionnés dans BindingSource
Ce que je veux, c’est que le deuxième formulaire puisse savoir quels éléments sont déjà sélectionnés pour pouvoir définir les éléments sélectionnés par défaut (actuellement, le deuxième formulaire par défaut est que tous les éléments ne sont pas cochés)
Codes pour le premier formulaire (EnrollMedicationFrm)
:
M3dEntities m3d = new M3dEntities(); enrollmeds _enrollmeds; EnrollMedSelectionFrm enrollselectfrm; public DataTable SelectedItems { get; set; } public ssortingng 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("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("PK_Items").ToSsortingng()); 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); } } } }
Codes pour le second formulaire (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; }
J’ai de nombreuses validations de formulaire avec ce stream, mais toutes ont ce problème 🙁 Une fois ce problème résolu, je pense que tout ou la plupart d’entre elles peuvent être corrigées aussi
Veuillez me guider sur la façon de résoudre ce problème, une autre approche ou même une solution de contournement pourrait être d’une grande aide, Merci beaucoup d’avance 🙂
Lorsque vous utilisez Entity Framework, vous n’avez pas besoin d’utiliser DataTable
. Vous devez plutôt vous appuyer sur des classes telles que List
, DbSet
, ObservableCollection
, BindingList
, etc.
Concentrons-nous sur les besoins actuels:
Ce que je veux, c’est avoir un moyen pour la 2e forme de savoir quels éléments sont déjà sélectionnés …
Considérez ces notes:
Lorsque vous liez un DataGridView
à une List
, la propriété DataBoundItem
de chaque ligne est de type T
Vous pouvez effectuer une recherche dans une collection Rows
de DataGridView
en appelant Cast
Puisque vous utilisez un DataGridView
pour vérifier certaines lignes, vous pouvez simplement avoir une colonne de case à cocher dans la grid et atsortingbuer son nom à CheckBoxColumn1
par exemple. Ensuite, dans votre bouton de sélection, vous pouvez trouver les éléments cochés de cette façon:
private void selectButton_Click(object sender, EventArgs e) { this.dataGridView1.EndEdit(); var checkedItems = this.dataGridView1.Rows.Cast() .Where(x => (bool?)x.Cells["CheckBoxColumn1"].Value == true) .Select(x => x.DataBoundItem) .Cast().ToList(); //use checkedItems }
Dans le code ci-dessus, je suppose que MyItem
est le type d’éléments de la liste que vous affichez dans la grid.