Search code examples
c#data-bindingcomboboxdatarepeater

c# Combobox binding in data repeater


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?


Solution

  • 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();                
            }
        }