I appreciate if someone can suggest to me how to bind Combobox properly to data repeater in windows form.
I have created a windows form with a data repeater. The data repeater contains a textbox and a combobox. I have a dataset which contains a data table with 2 columns namely “Value” and “OverflowBehaviour”. I bound the textbox to “Value” and the combobox to “OverflowBehaviour”. The following codes show creating the dataset and binding it to the textbox and combobox:
private void Form1_Load(object sender, EventArgs e)
{
bindingsource = new BindingSource();
ds = new DataSet("Preferences");
DataTable table = new DataTable("Preference");
table.Columns.Add("Value");
table.Columns.Add("OverflowBehaviour");
for (int i = 1; i <= 8; i++)
{
if (i < 5)
table.Rows.Add(i, ValueTypeAutoIncrementOverflowBehaviour.Exception);
else
table.Rows.Add(i, ValueTypeAutoIncrementOverflowBehaviour.Wrap);
}
ds.Tables.Add(table);
bindingsource.DataSource = ds;
bindingsource.DataMember = "Preference";
textBox1.DataBindings.Add(new Binding("Text", bindingsource, "Value", true, DataSourceUpdateMode.OnValidation));
comboBox1.DataBindings.Add("SelectedItem", bindingsource, "OverflowBehaviour", false, DataSourceUpdateMode.OnValidation);
dataRepeater.DataSource = bindingsource;
}
The “OverflowBehaviour” is an enum defined as follows:
public enum ValueTypeAutoIncrementOverflowBehaviour
{
Wrap,
Exception,
}
I read from this post ComboBox On DataRepeater Control Shares Selected Index that I need to manually map the combobox’s data source in the ItemCloned event, which I did:
void dataRepeater_ItemCloned(object sender, Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs e)
{
var Combo = (ComboBox)e.DataRepeaterItem.Controls.Find("comboBox1", false)[0];
Combo.DataSource = System.Enum.GetValues(typeof(ValueTypeAutoIncrementOverflowBehaviour));
}
I have also implemented the DrawItem as suggested in the same post. The codes are shown below.
void dataRepeater_DrawItem(object sender, Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs e)
{
var DataRepeater = (Microsoft.VisualBasic.PowerPacks.DataRepeater)sender;
var Combo = (ComboBox)e.DataRepeaterItem.Controls.Find("comboBox1", false)[0];
Combo.SelectedItem = ((List<ValueTypeAutoIncrementOverflowBehaviour>)DataRepeater.DataSource)[e.DataRepeaterItem.ItemIndex];
}
But, when I ran the project, it failed with error message at the last line. The error message is error to cast object of type 'System.Windows.Forms.BindingSource' to type 'System.Collections.Generic.List`1[WindowsFormsApplication1.Form1+ValueTypeAutoIncrementOverflowBehaviour]. I could not access any field within DataRepeater.DataSource, which was shown in the post.
Can anyone suggest what is the solution please? Is there a better way to bind combobox in data repeater in windows form please?
You can try this:
void dataRepeater_ItemCloned(object sender, Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs e)
{
var Combo = (ComboBox)e.DataRepeaterItem.Controls.Find("comboBox1", false)[0];
Combo.DataSource = System.Enum.GetValues(typeof(ValueTypeAutoIncrementOverflowBehaviour));
}
void dataRepeater_DrawItem(object sender, Microsoft.VisualBasic.PowerPacks.DataRepeaterItemEventArgs e)
{
var Combo = (ComboBox)e.DataRepeaterItem.Controls["comboBox1"];
if (ds.Tables["Preference"].Rows[e.DataRepeaterItem.ItemIndex]["OverflowBehaviour"].ToString() == "Exception")
{
Combo.Text = "Exception";
}
else
{
Combo.Text = "Wrap";
}
}
void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
{
var combo = (ComboBox)sender;
var DataRepeaterItem = (Microsoft.VisualBasic.PowerPacks.DataRepeaterItem)combo.Parent;
//Update dataset
if (ds.Tables["Preference"].Rows[DataRepeaterItem.ItemIndex]["OverflowBehaviour"].ToString() != combo.SelectedItem.ToString())
{
ds.Tables["Preference"].Rows[DataRepeaterItem.ItemIndex]["OverflowBehaviour"] = combo.SelectedItem.ToString();
}
}