locked
Binding enum values to combobox RRS feed

  • Question

  • I get how to bind the enum to the combobox what I don't get is how to ensure that when I navigate off a record that the enum value is read by the bindingsource navigator.

     

    Friend Enum Cycle

    Weekly

    Monthly

    Quarterly

    End Enum

     

    When my form loads the value come into the combobox just fine but the selected value is incorrect. As a matter of fact when I move to the next record the selected item in my combobox remains the same. Should I have to manually check the value of the cycle property on the bindingsource and manually set the selected value of the combobox each time? This seems ridiculous! I might as well forget the stupid enum and store plain old text values in my database and set the combobox selectedText property instead!

     

    Can anyone tell me how to bind to an enum value to a combobox so that when the selected value/item changes that the combobox reflects the change?

     

    Thursday, April 3, 2008 5:18 AM

Answers

  • Hi Dmano,

     

    You can refer to the following code:

     

    Code Snippet

    public Form2()

            {

                InitializeComponent();

            }

     

            private void Form2_Load(object sender, EventArgs e)

            {

                List<Customer> customers = new List<Customer>();

                customers.Add(new Customer(MyType.A));

                customers.Add(new Customer(MyType.B));

                customers.Add(new Customer(MyType.C));

     

                BindingSource bs = new BindingSource();

                bs.DataSource = customers;

                this.bindingNavigator1.BindingSource = bs;

     

                this.comboBox1.DataSource = Enum.GetValues(typeof(MyType));

                this.comboBox1.DataBindings.Add("SelectedItem", bs, "Type", true);

            }

        }

     

        public class Customer

        {

            private MyType type;

     

            public MyType Type

            {

                get { return type; }

                set { type = value; }

            }

     

            public Customer(MyType t)

            {

                this.type = t;

            }

        }

     

        public enum MyType

        {

            A,

            B,

            C

        }

     

     

     

    Regards,

    Roy Zhou

    Tuesday, April 8, 2008 2:09 AM

All replies

  • Hi Dmano,

     

    Based on my understanding, you want to bind the comboBox to an enumeration directly. If I have misunderstood you, please feel free to tell me, thanks.

     

    Unfortunately, you cannot set enumeration as binding source for complex data binding. There are some restriction to the objects which you want it to be the DataSource. And you can work around using array instead.

     

     

    There are two Binding types, one is simple data binding other one is complex data binding. Your situation above is complex data binding, so the object to be as DataSource should implement IList interface. However, enum dose not implement IList interface, also, it's value type. For something more about data binding you can refer to the following link to learn more.

     

     

    http://www.codeproject.com/KB/database/databindingconcepts.aspx

     

     

     

    Hope you can understannd !

    Regards,

    Roy Zhou

    Monday, April 7, 2008 9:43 AM
  • Thanks for your response.

     

    I realized that I was trying to ski uphill so I gave up. I'm still using the enum to bind to the combobox's datasource property but what I've done as a work around it to use the bindingsource control's positionchanged event to keep the combobox in sync...so to speak.

     

    Let me eloborate.

     

    During the load event, and before I fill the dataset I do the following:

     

    cboPayCycle.DataSource = [enum].getvalues(gettype(PayCycles))

     

    Then during the bindingsource's PositionChanged event I add this code

     

    Dim Employee as EmployeeRow = CType(CType(bsEmployee.Current, DataRowView).Row,EmployeeRow)

    cboPayCycle.SelectedItem = CType(PayCycles, Employee.PayCycle)

     

    It ain't pretty but it's doing something right.

     

    Hope this can be of some help or at least get some others to thinking of a more elegant solution

    Monday, April 7, 2008 2:03 PM
  • Hi Dmano,

     

    You can refer to the following code:

     

    Code Snippet

    public Form2()

            {

                InitializeComponent();

            }

     

            private void Form2_Load(object sender, EventArgs e)

            {

                List<Customer> customers = new List<Customer>();

                customers.Add(new Customer(MyType.A));

                customers.Add(new Customer(MyType.B));

                customers.Add(new Customer(MyType.C));

     

                BindingSource bs = new BindingSource();

                bs.DataSource = customers;

                this.bindingNavigator1.BindingSource = bs;

     

                this.comboBox1.DataSource = Enum.GetValues(typeof(MyType));

                this.comboBox1.DataBindings.Add("SelectedItem", bs, "Type", true);

            }

        }

     

        public class Customer

        {

            private MyType type;

     

            public MyType Type

            {

                get { return type; }

                set { type = value; }

            }

     

            public Customer(MyType t)

            {

                this.type = t;

            }

        }

     

        public enum MyType

        {

            A,

            B,

            C

        }

     

     

     

    Regards,

    Roy Zhou

    Tuesday, April 8, 2008 2:09 AM
  • If i understand well you want that the BindingSource is updated as soon as the user changes his selection in the ComboBox... This can be achieved by subscribing to the SelectionChangedCommitted event...

    Code Snippet

    combobox_SelectionChangeCommited(object sender, EventArgs e)
    {
      foreach(DataBinding binding in combobox.DataBindings)
      {
          binding.WriteValue();
      }
    }


    The DateTimePicker control exposes this same behaviour and i got tired of writing all those eventhandlers so i wrote a little Extender that does it "automagically": http://www.timvw.be/dont-wait-until-the-datetimepicker-has-lost-focus-to-write-back-the-values/

    And although the example is focussed on DataGridViewComboboxColumn (a child of ComboboxColumn) the following could inspire you too: http://www.timvw.be/exploring-datagridviewcomboboxcolumn-databinding/
    Tuesday, April 8, 2008 6:33 AM
  • Hi,
    I post a solution related to that sometime earlier on my blog. Please visit

    Thanks.

    Adil - MCP
    • Proposed as answer by Adil Mughal Sunday, January 25, 2009 9:04 AM
    Sunday, January 25, 2009 9:04 AM
  • that is one way.

    another way is more generic and personal prefer in an application

    	fillCbx(MyType.A, soundCbx);
    
    	public void fillCbx(Enum enuma, ComboBox cbx)
    	{
    		cbx.DataSource = null;
    		cbx.DataSource = System.Enum.GetNames(enuma.GetType());
    	}
    
    of course the member fillCbx is best as a public static class public member in a multi-form application

    Thursday, March 5, 2015 10:13 PM