我想在DataGridView中显示以下数据:
DataEntry[] data = new[]{
new DataEntry(){Name = "A", Entries = new []{ "1", "2"}},
new DataEntry(){Name = "B", Entries = new []{ "1", "2", "3"}}};
“Name”将是一个简单的TextBox字段,“Entries”是一个ComboBox,其中可供选择的项目是列表中的元素。
所以在这个例子中会有2行(下面是datagridview的样子):
Name Entries
Row1 : A <choice of "1" or "2">
Row1 : B <choice of "1" or "2" or "3">
我的问题是,如何绑定这些数据?!我查看了DataPropertyName,DisplayMember和ValueMember属性......但是无法解决这个问题。
下面是代码 - 注释,我需要添加神奇的几行来为条目列设置DataSource等。
public partial class Form1 : Form
{
DataEntry[] data = new[]{
new DataEntry(){Name = "A", Entries = new []{ "1", "2"}},
new DataEntry(){Name = "B", Entries = new []{ "1", "2", "3"}}};
public Form1()
{
InitializeComponent();
dataGridView1.AutoGenerateColumns = false;
var nameCol = new DataGridViewTextBoxColumn();
nameCol.DataPropertyName = "Name";
var entriesCol = new DataGridViewComboBoxColumn();
//entriesCol. ???? = "Entries"; !!
dataGridView1.Columns.AddRange(new DataGridViewColumn[] { nameCol, entriesCol });
dataGridView1.DataSource = data;
}
}
public class DataEntry
{
public string Name { get; set; }
public IEnumerable<string> Entries { get; set; }
}
答案 0 :(得分:4)
今天早上进来,10分钟后我就开始工作了!
解决方案是订阅“DataBindingComplete”事件,然后遍历每一行并在每个ComboBoxCell上设置数据源。有一个更优雅的解决方案会很高兴 - 但是嘿 - 它有效!
以下是我在原始问题中提交的代码示例的工作版本:
public partial class Form1 : Form
{
DataEntry[] data = new[]{
new DataEntry(){Name = "A", Entries = new []{ "1", "2", "3", "4"}},
new DataEntry(){Name = "B", Entries = new []{ "1", "2", "3"}}};
string[] cols = new[] { "col1", "col2" };
public Form1()
{
InitializeComponent();
dataGridView1.AutoGenerateColumns = false;
var nameCol = new DataGridViewTextBoxColumn();
nameCol.DataPropertyName = "Name";
var entriesCol = new DataGridViewComboBoxColumn();
entriesCol.Name = "Entries";
dataGridView1.Columns.AddRange(new DataGridViewColumn[] { nameCol, entriesCol });
dataGridView1.DataSource = data;
dataGridView1.DataBindingComplete += new DataGridViewBindingCompleteEventHandler(dataGridView1_DataBindingComplete);
}
void dataGridView1_DataBindingComplete(object sender, DataGridViewBindingCompleteEventArgs e)
{
for (int i = 0; i < dataGridView1.Rows.Count; i++)
{
DataGridViewComboBoxCell comboCell = (DataGridViewComboBoxCell)dataGridView1.Rows[i].Cells["Entries"];
DataEntry entry = dataGridView1.Rows[i].DataBoundItem as DataEntry;
comboCell.DataSource = entry.Entries;
comboCell.Value = entry.Entries.First();
}
}
}
public class DataEntry
{
public string Name { get; set; }
public IEnumerable<string> Entries { get; set; }
}
答案 1 :(得分:1)
我最近不得不这样做,并找到了一个不同的解决方案。
我使用了2个BindingSource来完成工作。第一个用于填充Datagrid,第二个用于ComboBoxColumn并使用第一个BindingSource,因为它的DataSource引用了DataMember。
这是我们可能想要绑定的DataObject:
class DataObject
{
public string Name { get; set; }
public string Value { get; set; }
public string [] ValueList { get; set; }
}
Designer文件看起来像:
// dataGridView1
this.dataGridView1.Columns.AddRange(new System.Windows.Forms.DataGridViewColumn[] {
this.nameDataGridViewTextBoxColumn,
this.valueDataGridViewTextBoxColumn});
this.dataGridView1.DataSource = this.bindingSource1;
// bindingSource1
this.bindingSource1.DataSource = typeof(SomeNamespace.DataObject);
// valueListBindingSource
this.valueListBindingSource.DataMember = "ValueList";
this.valueListBindingSource.DataSource = this.bindingSource1;
// nameDataGridViewTextBoxColumn
this.nameDataGridViewTextBoxColumn.DataPropertyName = "Name";
// valueDataGridViewTextBoxColumn
this.valueDataGridViewTextBoxColumn.DataPropertyName = "Value";
this.valueDataGridViewTextBoxColumn.DataSource = this.valueListBindingSource;
然后一个简单的表格看起来像:
public Form1 ()
{
InitializeComponent ();
m_objects = new List<DataObject> {
new DataObject { Name = "foo", ValueList = new [] { "1", "2", "3", "4" }},
new DataObject { Name = "bar", ValueList = new [] { "a", "b", "c" }}
};
bindingSource1.DataSource = m_objects;
}
private IList<DataObject> m_objects;