DataGridViewComboBoxCell Binding — недопустимое значение

Я пытаюсь связать отдельные ячейки ComboBox в DataGridView с пользовательским классом и продолжаю получать сообщение об ошибке

Недопустимое значение DataGridViewComboBoxCell.

В настоящее время я назначаю источник данных для ячейки IList<ICustomInterface> из словаря, который у меня есть. Однако при настройке источника данных индекс для ComboBoxCell не устанавливается, поэтому для него выбрано недопустимое значение.

Я пытаюсь понять, как заставить его выбрать реальное значение, например. 0-й элемент в списке дан для устранения этой ошибки или поиска другого способа решения проблемы. У кого-нибудь есть предложения?


person Ian    schedule 17.03.2009    source источник


Ответы (10)


Мне удалось найти решение вскоре после публикации вопроса. Для всех остальных:

Проблема заключалась в том, что я пытался присвоить DataGridViewComboBoxCell.Value объекту, ожидая, что, поскольку Cell привязан к источнику данных, он автоматически найдет объект в источнике и обновит его.

На самом деле это не так, вам действительно нужно установить значение, равное значению свойства ValueMember, чтобы оно правильно обновляло значение и привязку. Я полагаю, что использовал свойство «Имя» как для ValueMember, так и для DisplayMember (управляет рендерингом в ячейке), поэтому установка значения interface.ToString() (а не экземпляра интерфейса) работает в большинстве случаев. Затем я перехватываю и игнорирую любые исключения DataError, возникающие при изменении источника.

person Ian    schedule 17.03.2009
comment
Для всех, кто натыкается на это, вы имеете в виду, что свойство ValueMember должно равняться значению ячейки — DisplayMember — это соответствующее поле, которое вы хотите видеть. - person Chris; 04.11.2010
comment
Другой тип ошибки заключается в том, что при использовании наборов данных тип столбца, на который указывает DataPropertyName, отличается от столбца, на который указывает свойство ValueMember (даже из Int32 и Int16!!!!). - person kindaska; 17.12.2019
comment
Другая возможная причина: значение по умолчанию из DataTable в DataSet недопустимо (в моем случае: значение по умолчанию для поля Id не существовало в DataTable во время выполнения) - person Peter Adam; 01.03.2020

Вот мое простое решение при использовании перечислений

ColumnType.ValueType = typeof (MyEnum);
ColumnType.DataSource = Enum.GetValues(typeof (MyEnum));

вы можете сделать это сразу после "InitializeComponent();"

person Sauleil    schedule 22.01.2014
comment
каким должно быть значение MyEnum? - person ziad mansour; 19.02.2016
comment
перечисление, которое вы хотите в своем поле со списком, которое соответствует вашим данным. - person Sauleil; 22.02.2016

После нескольких часов испытаний я наконец нашел решение, которое работает.

// 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)
}

Вот и все.

person Community    schedule 18.08.2009
comment
@NaSo помни! нужно лечить проблему, а не игнорировать ее. кстати, вы связали cellCombo.DataSource, это совершенно неправильно. на самом деле DataGridViewComboBoxCell.DataSource будет привязано автоматически, когда вы установите DataGridViewComboBoxColumn.DataSource - person Rzassar; 13.12.2012

У меня такая же проблема.

В моем случае решением было заполнить адаптер данных таблицы внешнего ключа. Это не заполнялось автоматически, и это было причиной проблемы.

В событии Page_Load:

Me.TblUserTypesTableAdapter.Fill(Me.DonateDataSet.tblUserTypes)
person Mark Jarzebowski    schedule 24.10.2010

Я с той же проблемой. После заполнения моего столбца ComboBox в (unbouod) DataGrid я решил свою проблему, установив свойство ValueMember для DataGridViewComboBoxColumn По-видимому, просто полагаться на свойство ToString() объектов в ComboBox недостаточно.

Фактический код:

/// <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     
person Carlos A merighe    schedule 09.05.2011

Ради людей, которые не борются так сильно, как я.

При привязке комбинации вы устанавливаете DisplayMember (что увидит пользователь) и ValueMember (что получит ваше приложение).

После их настройки вам нужно настроить значение, и здесь оно не работает. В основном ТИП значения должен быть тем же ТИПОМ, что и ValueMember.

Итак, если ваш элемент значения является идентификатором, очевидно, его тип INT, и вам нужно установить значение в int, например, Cell.Value = 1;.

person SubqueryCrunch    schedule 11.12.2015

использовать обработчик событий DataError,

private void shahriartableDataGridView_DataError(object sender, DataGridViewDataErrorEventArgs e)
        {
            //You don't have to write anything here !
        }

и ваши типы данных DisplayMember и ValueMember должны быть одинаковыми, в моем случае у меня есть CountryName для обоих. У меня все работает отлично...!!

person Md Shahriar    schedule 20.12.2016

Вот полный пример с базовой формой и DataGridView, добавленным через конструктор:

Настройка и привязки:

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;

}

Некоторые классы:

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; }
}
person KyleMit    schedule 14.11.2019

Установите нулевое значение в ячейку:

dataGridView.CurrentRow.Cells[NAME].Value = null;
person Varo    schedule 20.10.2013

У меня была такая же проблема. Сообщение попало на 100%. Значения для поля со списком были такими: Exact, StartsWith... и я пытался установить значение Exactă (не точно). Это происходило автоматически, когда я читал DataTable для DataGridView из файла .xml с помощью DataTable.ReadXml(...). Значения в файле .xml были выключены.

person GoTo    schedule 24.02.2018