DataGridViewComboBoxColumn DataSource? - PullRequest
       17

DataGridViewComboBoxColumn DataSource?

5 голосов
/ 05 октября 2011

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

  • CodeID
  • CodeName
  • ComboBox с DisplayMember типа TypeName, ValueMember типа ID

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

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

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

Редактировать: похоже, проблема вызвана моим желанием иметь отдельный элемент для DisplayMember и 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"
}

edit : typeList - это простое DataTable, заполненное следующим:

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

Ответы [ 2 ]

6 голосов
/ 05 октября 2011

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

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

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

_ItemsGrid.DataSource = items;
4 голосов
/ 07 октября 2011

Хорошо, я придумал пример 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;
      }
   }
...