问题
I'm trying to bind separate ComboBox cells within a DataGridView to a custom class, and keep getting an error
DataGridViewComboBoxCell value is not valid
I'm currently assigning the data source for the cell to an IList<ICustomInterface>
from a Dictionary I've got. Upon setting the data source however, the index for the ComboBoxCell
isn't set, so it has an invalid value selected.
I'm trying to figure out how to get it to select a real value, e.g. the 0th item within the list it has been given to remove this error, or find another way to solve the problem. Anyone have any suggestions?
回答1:
I managed to find the solution not long after posting the question. For anyone else:
The problem was that I was trying to assign the DataGridViewComboBoxCell.Value
to an object, expecting that because the Cell was bound to a data source that it would automatically find the object in the source and update.
This wasn't actually the case, you actually need to set the value equal to that of the ValueMember
property for it to correctly update the value and binding. I believe I was using a property 'Name' for both ValueMember
and DisplayMember
(controls how the renders in the cell) so setting the Value to interface.ToString()
(rather than the interface instance) works for the majority of cases. Then I catch and ignore any DataError exceptions that occur while I'm changing the source around.
回答2:
Here's my simple solution when using enums
ColumnType.ValueType = typeof (MyEnum);
ColumnType.DataSource = Enum.GetValues(typeof (MyEnum));
you can do that just after "InitializeComponent();"
回答3:
Afters hours of trials, I finally found a solution that works.
// Create a DataGridView
System.Windows.Forms.DataGridView dgvCombo = new System.Windows.Forms.DataGridView();
// Create a DataGridViewComboBoxColumn
System.Windows.Forms.DataGridViewComboBoxColumn colCombo = new
System.Windows.Forms.DataGridViewComboBoxColumn();
// Add the DataGridViewComboBoxColumn to the DataGridView
dgvCombo.Columns.Add(colCombo);
// Define a data source somewhere, for instance:
public enum DataEnum
{
One,
Two,
Three
}
// Bind the DataGridViewComboBoxColumn to the data source, for instance:
colCombo.DataSource = Enum.GetNames(typeof(DataEnum));
// Create a DataGridViewRow:
DataGridViewRow row = new DataGridViewRow();
// Create a DataGridViewComboBoxCell:
DataGridViewComboBoxCell cellCombo = new DataGridViewComboBoxCell();
// Bind the DataGridViewComboBoxCell to the same data source as the DataGridViewComboBoxColumn:
cellCombo.DataSource = Enum.GetNames(typeof(DataEnum));
// Set the Value of the DataGridViewComboBoxCell to one of the values in the data source, for instance:
cellCombo.Value = "Two";
// (No need to set values for DisplayMember or ValueMember.)
// Add the DataGridViewComboBoxCell to the DataGridViewRow:
row.Cells.Add(cellCombo);
// Add the DataGridViewRow to the DataGridView:
dgvCombo.Rows.Add(row);
// To avoid all the annoying error messages, handle the DataError event of the DataGridView:
dgvCombo.DataError += new DataGridViewDataErrorEventHandler(dgvCombo_DataError);
void dgvCombo_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
// (No need to write anything in here)
}
That is all.
回答4:
I had the same problem.
In my case the solution was to fill the data adapter of the Foreign key table. This was not being automatically filled and this was the cause of the problem.
In the Page_Load
Event:
Me.TblUserTypesTableAdapter.Fill(Me.DonateDataSet.tblUserTypes)
回答5:
I am having the same problem. After populating my ComboBox column in the (unbouod) DataGrid, I solved my problem by setting the ValueMember property of the DataGridViewComboBoxColumn
Apparently, just relying on the ToString()
property of the objects in the ComboBox is not enough.
Actual code:
/// <summary>
/// Populate the dataGridSplitVolumes data grid with all existing qualifications for the plan.
/// </summary>
/// <param name="bonus"></param>
private void PopulateDataGridSplitVolumes(Bonus_Group bonus)
{
try
{
List<Qualification> qualifications = Qualification.Load(this.groupBonus.PlanID, this.ConnectionString);
foreach (Qualification qual in qualifications)
{
DataGridViewComboBoxColumn col = (DataGridViewComboBoxColumn)this.dataGridSplitVolumes.Columns[0];
col.Items.Add(qual);
}
SplitVolumeGrid_QualificationColumn.ValueMember = "Name";
}
catch (Exception ex)
{
#if DEBUG
System.Diagnostics.Debugger.Break();
#endif
throw ex;
}
}//PopulateDataGridSplitVolumes
回答6:
For the sake of people not struggling as much as i did.
When binding the combo you are setting a DisplayMember (what the user will see) and ValueMember (what your application will get).
After setting up these you need to set up the Value and this is where it fails. Basically the TYPE of the value needs to be the same TYPE as the ValueMember.
So if your value member is an ID obviously its of type INT and you need to set your value to int for example Cell.Value = 1;.
回答7:
use DataError Event handler,
private void shahriartableDataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
{
//You don't have to write anything here !
}
and your DisplayMember and ValueMember data type should be the same, in my case I have CountryName for both. Everything works fine for me...!!
回答8:
Set a null value to the cell:
dataGridView.CurrentRow.Cells[NAME].Value = null;
回答9:
I was having the same problem. The message was 100% spot on. The values for the combobox were like: Exact, StartsWith... and I was trying to set the value Exactă (not Exact). This was happening automatically as I was reading the DataTable for the DataGridView from an .xml file with DataTable.ReadXml(...). The values in the .xml file were off.
回答10:
Here's a complete example with a basic form and DataGridView
added via the designer:
Setup and bindings:
private void Form1_Load(object sender, EventArgs e)
{
var colors = new List<Code>()
{
new Code() {Value= "R", Text = "Red"},
new Code() {Value= "G", Text = "Green"},
new Code() {Value= "B", Text = "Blue"}
};
var users = new List<User>()
{
new User() {Name = "Briana", FavoriteColor = "B"},
new User() {Name = "Grace", FavoriteColor = "G"}
};
var colorCol = new DataGridViewComboBoxColumn();
colorCol.DataSource = colors;
colorCol.DisplayMember = "Text";
colorCol.ValueMember = "Value";
colorCol.DataPropertyName = "FavoriteColor";
dataGridView1.Columns.Add(colorCol);
dataGridView1.DataSource = users;
}
Some classes:
public class Code
{
public string Value { get; set; }
public string Text { get; set; }
}
public class User
{
public string Name { get; set; }
public string FavoriteColor { get; set; }
}
来源:https://stackoverflow.com/questions/654829/datagridviewcomboboxcell-binding-value-is-not-valid