Master/Detail issue in DataGridView using DataGridViewComboBoxColumn
In the last few days I was trying to create a DataGridView that shows
data from two tables related with a foreign key constraint. The
DataGridView should have 2 columns. The first one, called 'Name' is a
bounded column that gets data from the first table and the second
column is an unbounded one of DataGridViewComboBoxColumn type that
shows 'details' from the second table. This is a classic example of,
lets say, region-city data binding. The DataGridView is formed by a
number of regions (each region represents one row in the grid) and for
each region a combo box shows the cities from that region...
I've tried the examples from MSDN and even the given examples, but with
no success... The error I get is: "DataGridViewComboBox cell value is
not valid".
The code should talk for itself:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
namespace nradatagridview
{
public partial class Form1 : Form
{
DataSet dsArticle;
BindingSource bsArticleSource;
DataGridView dgArticleGrid;
public Form1()
{
InitializeComponent();
}
private void Form1_Load(object sender, EventArgs e)
{
dsArticle = LoadDBData();
bsArticleSource = new BindingSource(dsArticle, "Articles");
InitializeGrid();
}
private void InitializeGrid()
{
dgArticleGrid = new DataGridView();
dgArticleGrid.Name = "MasterGrid";
dgArticleGrid.MultiSelect = false;
dgArticleGrid.AutoGenerateColumns = false;
dgArticleGrid.DataSource = bsArticleSource;
dgArticleGrid.AllowUserToAddRows = false;
dgArticleGrid.SelectionMode = DataGridViewSelectionMode.FullRowSelect;
dgArticleGrid.AlternatingRowsDefaultCellStyle.BackColor =
SystemColors.InactiveCaptionText;
dgArticleGrid.Dock = DockStyle.Fill;
dgArticleGrid.VirtualMode = true;
//Name (ID) column (textbox)
DataGridViewTextBoxColumn colGestID = new DataGridViewTextBoxColumn();
colGestID.Name = "colGestID";
colGestID.DataPropertyName = "RegionName";
colGestID.HeaderText = "Region";
//colName.AutoSizeMode = DataGridViewAutoSizeColumnMode.DisplayedCells;
colGestID.ReadOnly = false;
dgArticleGrid.Columns.Add(colGestID);
//Details (combobox)
DataGridViewComboBoxColumn colCombo = new DataGridViewComboBoxColumn();
colCombo.Name = "colCombo";
colCombo.HeaderText = "ComboTest";
BindingSource bs = new BindingSource();
bs.DataSource = bsArticleSource;
bs.DataMember = "FK_Relation";
colCombo.DataSource = bs;
colCombo.DataPropertyName = "SelectedCityName"; //the exception is
trown here, why?
colCombo.DisplayMember = "CityName";
colCombo.ValueMember = "CityName";
colCombo.ReadOnly = false;
colCombo.AutoSizeMode =
DataGridViewAutoSizeColumnMode.None;
dgArticleGrid.Columns.Add(colCombo);
this.Controls.Add(dgArticleGrid);
}
private DataSet LoadDBData()
{
try
{
DataSet ds = new DataSet();
using (SqlConnection conn = new SqlConnection("Data Source=BLA;Initial
Catalog=BLA;User ID=BLA"))
{
conn.Open();
SqlCommand cmd = new SqlCommand();
cmd.CommandText = "select * from
regions";
cmd.Connection = conn;
using (SqlDataReader drArticles = cmd.ExecuteReader())
{
ds.Load(drArticles, LoadOption.OverwriteChanges, new string[] {
"Regions" });
}
//cmd.CommandText = "select * from cities";
using (SqlDataReader drGest = cmd.ExecuteReader())
{
ds.Load(drGest, LoadOption.OverwriteChanges, new string[] { "Cities" });
}
ds.Relations.Add(new
DataRelation("FK_Relation",ds.Tables["Regions"].Columns["ID"],ds.Tables["Cities"].Columns["RegionID"]));
conn.Close();
}
return ds;
}
catch (Exception e)
{
MessageBox.Show(e.ToString());
return null;
}
}
}
}
}
}
The table structure looks like this:
Region Table:
ID,RegionName,.....,SelectedCityName
City Table:
ID,RegionID,CityName,...

