问题
I have a Many to Many mixed with some Master-Detail DataGrid setup.
- 4 DataGridView
- 6 Entities (2 mapping tables)
- 5 Data relations
To give you a visual image, there is 1 big Employe DGV (DataGridView), and 3 smaller ones which updates depending on the Employe DGV selected row.
One of the 3 smaller grid is a really simple relation without a mapping table.
The other 2, however, displays a mapping table rows that uses formatedinfo of the entity it is mapping to. Those 2 DGV only have 1 column, a ComboBox with a formated string (overriden .ToString()) which (should) have the underlying object that the mapping is pointing to (EF will handle setting the ID accordingly when receiving the entire object). However, when I try to add a new rows, it will say it is unable to convert a String to a Put Object Name Here. This led me to think that if you did not set a ValueMember, the combobox would try to get a string representation using .ToString(). So I attempted to bypass that behavior by adding a Self property to the entity which simply returns himself. No success, it is still trying to convert a string somewhere.
The exact error (in french) is:
System.FormatException: Cast non valide de 'System.String' en 'InvInformatique.logiciels'.
Which traducts to "Invalid cast from System.String to InvInformatique.logiciels.
Code
InventaireInformatiqueEntities iidb = new InventaireInformatiqueEntities();
bsEmployes.DataSource = iidb.employes;
bsMateriels.DataSource = iidb.materiels;
bsLogiciels.DataSource = iidb.logiciels;
bsLogicielEmployeMaps.DataSource = iidb.logiciel_employe_maps; // Needed to provoke the load query
bsAcces.DataSource = iidb.acces;
bsAccesEmployeMaps.DataSource = iidb.acces_employe_maps; // Needed to provoke the load query
dgvEmployes.AutoGenerateColumns = false;
dgvEmployes.Columns.AddRange(
new DataGridViewTextBoxColumn { Name = "Nom", DataPropertyName = "nom" },
new DataGridViewTextBoxColumn { Name = "Département", DataPropertyName = "departement" }
);
dgvEmployeMateriels.AutoGenerateColumns = false;
dgvEmployeMateriels.Columns.AddRange(
new DataGridViewTextBoxColumn { HeaderText = "Nom", DataPropertyName = "nom" },
new DataGridViewTextBoxColumn { HeaderText = "Satisfaction", Name = "satisfaction", DataPropertyName = "satisfaction" }
);
dgvEmployeAcces.AutoGenerateColumns = false;
dgvEmployeAcces.Columns.AddRange(
new DataGridViewComboBoxColumn { HeaderText = "Accès", DataPropertyName = "acces", DataSource = bsAcces }
);
dgvEmployeLogiciel.AutoGenerateColumns = false;
dgvEmployeLogiciel.Columns.AddRange(
new DataGridViewComboBoxColumn { HeaderText = "Logiciels", DataPropertyName = "logiciels", DataSource = bsLogiciels }
);
dgvEmployes.DataSource = bsEmployes;
dgvEmployeMateriels.DataBindings.Add(new Binding("DataSource", bsEmployes, "materiels"));
dgvEmployeLogiciel.DataBindings.Add(new Binding("DataSource", bsEmployes, "logiciel_employe_maps"));
dgvEmployeAcces.DataBindings.Add(new Binding("DataSource", bsEmployes, "acces_employe_maps"));
Database
Employes
->id
->nom
->departement
Acces
->id
->nom
->description
Logiciel
->id
->nom
Materiel
->id
->employe_id
->nom
->description
Acces_Employe_Maps
->id
->acces_id
->employe_id
Logiciel_Employe_Maps
->id
->logiciel_id
->employe_id
Database relations
Employes <-> Logiciel_Employe_Maps <-> Logiciels
Employes <-> Acces_Employe_Maps <-> Acces
Employes -> Materiel
回答1:
Ok so, DataGridViews don't like using ToString() to get a DisplayMember. When I keep DisplayMember empty or use my Self property, it bugs out the ValueMember.
Setting DisplayMember = "nom", ValueMember="Self" worked perfectly.
Edit
This also worked:
Add to EF partial class:
public string FormatedName { get { return this.ToString(); } }
Change in column definition:
DisplayMember = "FormatedName", ValueMember = "Self"
来源:https://stackoverflow.com/questions/12515745/datagridviewcomboboxcolumn-not-taking-valuemember