C # Winform (Entity Framework) – conversion de DataGridView ou BindingSource en databound vers DataTable

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) :

1er 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) :

2ème 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.