Источник данных DataGridViewComboBoxColumn?

#c# #winforms #data-binding #datagridview #datatable

#c# #winforms #привязка данных #datagridview #datatable

Вопрос:

Я пытаюсь что-то настроить в DataGridView . Кажется, это должно быть довольно просто, но у меня проблемы. Я хочу отобразить три столбца:

  • CodeID
  • Кодовое имя
  • ComboBox с отображаемым элементом TypeName, значением TypeID

Я хочу иметь возможность выбирать из всех возможных значений TypeName . Вот моя дилемма:

Если я загружу все это в один DataTable и установлю DataGridView как DataSource , я могу отобразить существующую TypeName для этой записи, но поле со списком не будет содержать никаких других значений. Если я установлю DataSource для DataGridViewComboBoxColumn отдельного DataTable , который включает все возможные TypeNames , существующее значение не отображается.

DataGridView действительно раздражает работа, поэтому будет оценено либо решение для этого, либо жизнеспособная альтернатива.

Редактировать: похоже, проблема вызвана тем, что я хочу иметь отдельный элемент для DisplayMember and ValueMember . Работает следующее, если я не беспокоюсь о том, чтобы установить ID как ValueMember :

 var typeColumn = new DataGridViewComboBoxColumn
{
    DataSource = typeList,
    DisplayMember = "Type",
    ValueMember = "Type",
    DataPropertyName = "Type"
}
  

Если я сделаю следующее, будут выбраны правильные типы, но я не могу изменить выбор в поле со списком:

 var typeColumn = new DataGridViewComboBoxColumn
{
    DataSource = typeList,
    DisplayMember = "Type",
    ValueMember = "TypeID",
    DataPropertyName = "TypeID"
}
  

Если я использую следующее, я получаю FormatException сообщение об ошибке при попытке заполнения:

 var typeColumn = new DataGridViewComboBoxColumn
{
    DataSource = typeList,
    DisplayMember = "Type",
    ValueMember = "TypeID",
    DataPropertyName = "Type"
}
  

редактировать: typeList простое DataTable заполняется следующим:

 SELECT DISTINCT IT.InsuranceTypeID, IT.[Type]
FROM InsuranceType IT
WHERE IT.ClientID = @ClientID
ORDER BY [Type]
  

Комментарии:

1. Устанавливаете ли вы DataPropertyName в DGVCBC? Кроме того, значок профиля epic. social.msdn.microsoft.com/forums/en-US/winformsdatacontrols /…

2. Можете ли вы опубликовать, как вы настраиваете typeList и структуру, которую вы добавляете в список? Типы DataPropertyName и ValueMember должны быть одинаковыми, вероятно, поэтому вы получаете исключение в последнем примере.

Ответ №1:

У меня была похожая (я думаю) проблема, и решением для меня было установить DataSource для DataGridViewComboBoxColumn перед установкой DataSource для DataGridView .

В моем случае моими источниками данных являются a List<T> и a BindingList<T> соответственно, но он должен работать так же с таблицами данных:

 DataGridViewComboBoxColumn categoryColumn = (DataGridViewComboBoxColumn)_ItemsGrid.Columns["CategoryID"];
categoryColumn.DataSource = categories;

_ItemsGrid.DataSource = items;
  

Комментарии:

1. К сожалению, это не помогло.

2. Это очень помогло мне при использовании Eloquera и привязке некоторого сложного класса к datagrid. Спасибо!

3. Этот ответ был волшебным для меня, найдя его 10 лет спустя.

Ответ №2:

Хорошо, я привел пример ClientInfo , и InsuranceDetails я думаю, что он может имитировать то, что вы пытаетесь сделать. Дайте мне знать, если эти детали не совсем верны. В этом примере будет заполнено DataGridViewComboBox и установлено значение на основе InsuranceDetails (в частности, в: InsurDetailz = all_insurance_types[2] )

    public partial class Form1 : Form
   {
      private ClientInfo _myClient;
      private BindingList<InsuranceDetails> all_insurance_types =
         new BindingList<InsuranceDetails>();

      public Form1()
      {
         InitializeComponent();

         DataGridView grid = new DataGridView();
         grid.Dock = DockStyle.Fill;
         grid.AutoGenerateColumns = true;

         all_insurance_types.Add(new InsuranceDetails(1, "Health"));
         all_insurance_types.Add(new InsuranceDetails(2, "Home"));
         all_insurance_types.Add(new InsuranceDetails(3, "Life"));

         var col = new DataGridViewComboBoxColumn
         {
            DataSource = all_insurance_types,
            HeaderText = "Insurance Type",
            DataPropertyName = "InsurDetailz",
            DisplayMember = "ItType",
            ValueMember = "Self",
         };

         _myClient = new ClientInfo { 
            InsurDetailz = all_insurance_types[2], Name = "Jimbo" };
         grid.Columns.Add(col);
         grid.DataSource = new BindingList<ClientInfo> { _myClient };
         this.Controls.Add(grid);

         this.FormClosing  = new FormClosingEventHandler(Form1_FormClosing);
      }

      void Form1_FormClosing(object sender, FormClosingEventArgs e)
      {
         // make sure its updated
         InsuranceDetails c = _myClient.InsurDetailz;
         string name = _myClient.Name;
         // Place breakpoint here to see the changes in _myClient 
         throw new NotImplementedException();
      }
   }

   class ClientInfo
   {
      public string Name { get; set; }
      public InsuranceDetails InsurDetailz { get; set; }
   }

   class InsuranceDetails
   {
      public int InsuranceTypeID { get; set; }
      public String ItType { get; set; }
      public InsuranceDetails Self { get { return this; } }

      public InsuranceDetails(int typeId, String itType)
      {
         this.InsuranceTypeID = typeId;
         this.ItType = itType;
      }
   }
  

Комментарии:

1. Секрет заключается в Self свойстве.