I get this error that I don't know how to properly prevent it from happening:

Cannot bind to the property or column SomeField on the DataSource.
Parameter name: dataMember

I'm including a zipped up project I created that simulates what is happening in my much larger application.

I have created two Data Source classes, and embedded Data2Source member object inside of Data1Source class.

I then added Data1Source object to Data Sources tool tab via wizard.

When I run this tabcontrol form, if I click on the Tab2 without having items in my Data2Source's list, I get this error and I don't know how to properly handle this when there are not yet items in its list. If I have at least one item in the Data2Source's List, I have no problem.
"SomeField", from the error message above, is a Property in Data2Source and is bound to a control on Tab2.

The idea is that user could create several Data1Source List items, each of them having 0 - many Data2Source List items. Data2Source List items cannot exist without corresponding item existing in the Data1Source List.

To create a Data2Source List item and see it run without error, uncomment the dataMgr.data2.Add(new Data2ListItem("Item 4", "someField text")); in the Form1_Load event:

private void Form1_Load(object sender, EventArgs e)
        {
            dataMgr = new DataManager();
            data1SourceBindingSource.DataSource = dataMgr.data1Source;

            for (int i = 0; i < dataMgr.data1.Count; i++)
                comboBox1.Items.Add(dataMgr.data1[i].Key);

            //////////////////////////////////////////////////////////////////////////////////
            // This line of code will stop the Exception.
            // As long is there is at least one Item in the data2.List, no binding error occurs.

            // dataMgr.data2.Add(new Data2ListItem("Item 4", "someField text"));

            //////////////////////////////////////////////////////////////////////////////////

            comboBox1.SelectedIndex = 0;
        }

If you uncomment out that line above that adds 1 item to Data2Source's List, you can switch to Tab2 and no problem; and you will also see you can change the combobox selection on the form and the Data Source binding to controls is also working.

Don't try to enter data in the textboxes because I created this test project only to resolve this particular issue I am having and I have not implemented or tested this project for other purposes.

Thanks for helping.

Recommended Answers

All 13 Replies

Here is what the code looks like. There are no tables, just simple binding to Data Source Object:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace DataSourceBindingTest
{
    public partial class Form1 : Form
    {
        public DataManager dataMgr;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            dataMgr = new DataManager();
            data1SourceBindingSource.DataSource = dataMgr.data1Source;

            for (int i = 0; i < dataMgr.data1.Count; i++)
                comboBox1.Items.Add(dataMgr.data1[i].Key);

            //////////////////////////////////////////////////////////////////////////////////
            // This line of code will stop the Exception.
            // As long as there is at least one Item in the data2.List, no binding error occurs.
            
            dataMgr.data2.Add(new Data2ListItem("Item 4", "someField text"));
            
            //////////////////////////////////////////////////////////////////////////////////

            comboBox1.SelectedIndex = 0;
        }

        private void comboBox1_SelectedIndexChanged(object sender, EventArgs e)
        {
            int selIndex = comboBox1.SelectedIndex;
            dataMgr.data1.index = selIndex;
            dataMgr.data2.index = dataMgr.data2.Find(comboBox1.Items[selIndex].ToString());
            data1SourceBindingSource.ResetCurrentItem();
            EnableControls();
        }

        private void EnableControls()
        {
            someFieldTextBox.Enabled = keyTextBox.Enabled = 
                dataMgr.data2.index >= 0 ? true : false;
        }

    }
}

////////////////////// form1.designer.cs
namespace DataSourceBindingTest
{
    partial class Form1
    {
        /// <summary>
        /// Required designer variable.
        /// </summary>
        private System.ComponentModel.IContainer components = null;

        /// <summary>
        /// Clean up any resources being used.
        /// </summary>
        /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
        protected override void Dispose(bool disposing)
        {
            if (disposing && (components != null))
            {
                components.Dispose();
            }
            base.Dispose(disposing);
        }

        #region Windows Form Designer generated code

        /// <summary>
        /// Required method for Designer support - do not modify
        /// the contents of this method with the code editor.
        /// </summary>
        private void InitializeComponent()
        {
            this.components = new System.ComponentModel.Container();
            System.Windows.Forms.Label keyLabel1;
            System.Windows.Forms.Label someFieldLabel;
            System.Windows.Forms.Label keyLabel;
            this.tabControl1 = new System.Windows.Forms.TabControl();
            this.tabPage1 = new System.Windows.Forms.TabPage();
            this.tabPage2 = new System.Windows.Forms.TabPage();
            this.keyTextBox = new System.Windows.Forms.TextBox();
            this.someFieldTextBox = new System.Windows.Forms.TextBox();
            this.data1SourceBindingSource = new System.Windows.Forms.BindingSource(this.components);
            this.keyTextBox1 = new System.Windows.Forms.TextBox();
            this.comboBox1 = new System.Windows.Forms.ComboBox();
            keyLabel1 = new System.Windows.Forms.Label();
            someFieldLabel = new System.Windows.Forms.Label();
            keyLabel = new System.Windows.Forms.Label();
            this.tabControl1.SuspendLayout();
            this.tabPage1.SuspendLayout();
            this.tabPage2.SuspendLayout();
            ((System.ComponentModel.ISupportInitialize)(this.data1SourceBindingSource)).BeginInit();
            this.SuspendLayout();
            // 
            // tabControl1
            // 
            this.tabControl1.Controls.Add(this.tabPage1);
            this.tabControl1.Controls.Add(this.tabPage2);
            this.tabControl1.Dock = System.Windows.Forms.DockStyle.Bottom;
            this.tabControl1.Location = new System.Drawing.Point(0, 48);
            this.tabControl1.Name = "tabControl1";
            this.tabControl1.SelectedIndex = 0;
            this.tabControl1.Size = new System.Drawing.Size(292, 262);
            this.tabControl1.TabIndex = 0;
            // 
            // tabPage1
            // 
            this.tabPage1.Controls.Add(keyLabel);
            this.tabPage1.Controls.Add(this.keyTextBox1);
            this.tabPage1.Location = new System.Drawing.Point(4, 22);
            this.tabPage1.Name = "tabPage1";
            this.tabPage1.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage1.Size = new System.Drawing.Size(284, 236);
            this.tabPage1.TabIndex = 0;
            this.tabPage1.Text = "tabPage1";
            this.tabPage1.UseVisualStyleBackColor = true;
            // 
            // tabPage2
            // 
            this.tabPage2.Controls.Add(someFieldLabel);
            this.tabPage2.Controls.Add(this.someFieldTextBox);
            this.tabPage2.Controls.Add(keyLabel1);
            this.tabPage2.Controls.Add(this.keyTextBox);
            this.tabPage2.Location = new System.Drawing.Point(4, 22);
            this.tabPage2.Name = "tabPage2";
            this.tabPage2.Padding = new System.Windows.Forms.Padding(3);
            this.tabPage2.Size = new System.Drawing.Size(284, 240);
            this.tabPage2.TabIndex = 1;
            this.tabPage2.Text = "tabPage2";
            this.tabPage2.UseVisualStyleBackColor = true;
            // 
            // keyLabel1
            // 
            keyLabel1.AutoSize = true;
            keyLabel1.Location = new System.Drawing.Point(53, 40);
            keyLabel1.Name = "keyLabel1";
            keyLabel1.Size = new System.Drawing.Size(28, 13);
            keyLabel1.TabIndex = 0;
            keyLabel1.Text = "Key:";
            // 
            // keyTextBox
            // 
            this.keyTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.data1SourceBindingSource, "Data2Source.Key", true));
            this.keyTextBox.Location = new System.Drawing.Point(87, 37);
            this.keyTextBox.Name = "keyTextBox";
            this.keyTextBox.Size = new System.Drawing.Size(100, 20);
            this.keyTextBox.TabIndex = 1;
            // 
            // someFieldLabel
            // 
            someFieldLabel.AutoSize = true;
            someFieldLabel.Location = new System.Drawing.Point(19, 96);
            someFieldLabel.Name = "someFieldLabel";
            someFieldLabel.Size = new System.Drawing.Size(62, 13);
            someFieldLabel.TabIndex = 2;
            someFieldLabel.Text = "Some Field:";
            // 
            // someFieldTextBox
            // 
            this.someFieldTextBox.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.data1SourceBindingSource, "Data2Source.SomeField", true));
            this.someFieldTextBox.Location = new System.Drawing.Point(87, 93);
            this.someFieldTextBox.Name = "someFieldTextBox";
            this.someFieldTextBox.Size = new System.Drawing.Size(100, 20);
            this.someFieldTextBox.TabIndex = 3;
            // 
            // data1SourceBindingSource
            // 
            this.data1SourceBindingSource.DataSource = typeof(DataSourceBindingTest.Data1Source);
            // 
            // keyLabel
            // 
            keyLabel.AutoSize = true;
            keyLabel.Location = new System.Drawing.Point(54, 54);
            keyLabel.Name = "keyLabel";
            keyLabel.Size = new System.Drawing.Size(28, 13);
            keyLabel.TabIndex = 0;
            keyLabel.Text = "Key:";
            // 
            // keyTextBox1
            // 
            this.keyTextBox1.DataBindings.Add(new System.Windows.Forms.Binding("Text", this.data1SourceBindingSource, "Key", true));
            this.keyTextBox1.Location = new System.Drawing.Point(88, 51);
            this.keyTextBox1.Name = "keyTextBox1";
            this.keyTextBox1.Size = new System.Drawing.Size(100, 20);
            this.keyTextBox1.TabIndex = 1;
            // 
            // comboBox1
            // 
            this.comboBox1.FormattingEnabled = true;
            this.comboBox1.Location = new System.Drawing.Point(29, 13);
            this.comboBox1.Name = "comboBox1";
            this.comboBox1.Size = new System.Drawing.Size(121, 21);
            this.comboBox1.TabIndex = 1;
            this.comboBox1.SelectedIndexChanged += new System.EventHandler(this.comboBox1_SelectedIndexChanged);
            // 
            // Form1
            // 
            this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
            this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
            this.ClientSize = new System.Drawing.Size(292, 310);
            this.Controls.Add(this.comboBox1);
            this.Controls.Add(this.tabControl1);
            this.Name = "Form1";
            this.Text = "Form1";
            this.Load += new System.EventHandler(this.Form1_Load);
            this.tabControl1.ResumeLayout(false);
            this.tabPage1.ResumeLayout(false);
            this.tabPage1.PerformLayout();
            this.tabPage2.ResumeLayout(false);
            this.tabPage2.PerformLayout();
            ((System.ComponentModel.ISupportInitialize)(this.data1SourceBindingSource)).EndInit();
            this.ResumeLayout(false);

        }

        #endregion

        private System.Windows.Forms.TabControl tabControl1;
        private System.Windows.Forms.TabPage tabPage1;
        private System.Windows.Forms.TabPage tabPage2;
        private System.Windows.Forms.BindingSource data1SourceBindingSource;
        private System.Windows.Forms.TextBox someFieldTextBox;
        private System.Windows.Forms.TextBox keyTextBox;
        private System.Windows.Forms.TextBox keyTextBox1;
        private System.Windows.Forms.ComboBox comboBox1;
    }
}

/////////////////// DataManager.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace DataSourceBindingTest
{
    public class DataManager
    {
        public Data1 data1;
        public Data2 data2;
        public Data1Source data1Source;

        public DataManager()
        {
            data1 = new Data1();
            data2 = new Data2();

            for (int i=0; i<30; i++)
            {
                data1.Add(new Data1ListItem("Item " + i));
            }

            data1Source = new Data1Source(data1, data2);
        }
    }
}


/////////////////// DataSource1.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace DataSourceBindingTest
{

    public class Data1ListItem
    {
        public string key;
        public string Key
        {
            get { return key; }
            set { key = value; }
        }

        public Data1ListItem(string key)
        {
            this.key = key;
        }
        public override string ToString()
        {
            return key.ToString();
        }
    }

    public class Data1 : List<Data1ListItem>
    {
        public int index;

        public Data1()
        {
        }

        public Data1ListItem Current()
        {
            return this[index];
        }

    }

    
    public class Data1Source : IEnumerable
    {
        public Data2Source data2Source;
        public Data1 data1;

        public Data1Source(Data1 data1, Data2 data2)
        {
            this.data1 = data1;
            data2Source = new Data2Source(data2);
        }

        public string Key
        {
            get { return data1.Current().key; }
            set { data1.Current().key = value; }
        }
        public Data2Source Data2Source // allows it to show up in Data Sources tab
        {
            get { return data2Source; }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new Data1SourceEnum(this);
        }
    }

    public class Data1SourceEnum : IEnumerator
    {
        Data1Source dataSrc;

        // Enumerators are positioned before the first element
        // until the first MoveNext() call.
        int position = -1;

        public Data1SourceEnum(Data1Source dataSrc)
        {
            this.dataSrc = dataSrc;
            dataSrc.data1.index = -1;
        }

        public bool MoveNext()
        {
            dataSrc.data1.index++;
            return (dataSrc.data1.index < dataSrc.data1.Count);
        }

        public void Reset()
        {
            dataSrc.data1.index = -1;
        }

        public object Current
        {
            get
            {
                try
                {
                    return dataSrc;
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
    }
}

///////////////// DataSource2.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;

namespace DataSourceBindingTest
{
    public class Data2ListItem
    {
        public string key;
        public string someField;
        public Data2ListItem(string key, string someField)
        {
            this.key = key;
            this.someField = someField;
        }
        public override string ToString()
        {
            return key.ToString();
        }

        public class Data2ItemComparer : IComparer<Data2ListItem>
        {
            public int Compare(Data2ListItem x, Data2ListItem y)
            {
                if (x == null)
                {
                    if (y == null)
                    {
                        // If x is null and y is null, they're
                        // equal. 
                        return 0;
                    }
                    else
                    {
                        // If x is null and y is not null, y
                        // is greater. 
                        return -1;
                    }
                }
                else
                {
                    // If x is not null...
                    //
                    if (y == null)
                    // ...and y is null, x is greater.
                    {
                        return 1;
                    }
                    else
                    {
                        // ...and y is not null, compare the 
                        // lengths of the two strings.
                        //
                        int retval = x.ToString().Length.CompareTo(y.ToString().Length);

                        if (retval != 0)
                        {
                            // If the strings are not of equal length,
                            // the longer string is greater.
                            //
                            return retval;
                        }
                        else
                        {
                            // If the strings are of equal length,
                            // sort them with ordinary string comparison.
                            //
                            return x.ToString().CompareTo(y.ToString());
                        }
                    }
                }
            }
        }

    }

    public class Data2 : List<Data2ListItem>
    {
        public int index;
        public Data2()
        {
            index = -1;
            Clear();
        }

        public Data2ListItem Current()
        {
            return this[index];
        }

        public int Find(string key)
        {
            Data2ListItem.Data2ItemComparer iComparer = new Data2ListItem.Data2ItemComparer();
            Data2ListItem item = new Data2ListItem(key, "");
            return this.BinarySearch(item, iComparer);
        }
    }

    public class Data2Source : IEnumerable
    {
        public Data2 data2;

        public Data2Source(Data2 data2)
        {
            this.data2 = data2;
        }

        public string Key
        {
            get {
                if (data2.index < 0)
                    return "";
                return data2.Current().key; 
            }
            set {
                if (data2.index < 0)
                    System.Diagnostics.Debug.Assert(false);
                data2.Current().key = value; 
            }
        }
        public string SomeField
        {
            get {
                if (data2.index < 0)
                    return "";
                return data2.Current().someField; 
            }
            set {
                if (data2.index < 0)
                    System.Diagnostics.Debug.Assert(false);
                data2.Current().someField = value; 
            }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new Data2SourceEnum(this);
        }

    }
    public class Data2SourceEnum : IEnumerator
    {
        Data2Source dataSrc;

        // Enumerators are positioned before the first element
        // until the first MoveNext() call.
        //int position = -1;

        public Data2SourceEnum(Data2Source dataSrc)
        {
            this.dataSrc = dataSrc;

            dataSrc.data2.index = -1;
        }

        public bool MoveNext()
        {
            dataSrc.data2.index++;
            return (dataSrc.data2.index < dataSrc.data2.Count);
        }

        public void Reset()
        {
            dataSrc.data2.index = -1;
        }

        public object Current
        {
            get
            {
                try
                {
                    return dataSrc;
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
    }
}

Its hard to tell. You didn't include enough of the project to compile (missing DataDictionary) but you did include your subversion files :)

Sorry, I uploaded the wrong/broken project. It's basically the code posted above, but I'll try zipping up the correct one again later.

Sorry, I uploaded the wrong/broken project. It's basically the code posted above, but I'll try zipping up the correct one again later.

Here is the correct project--thanks!

I promise it is a compilable project--:P It is really small and to the point.

If anybody who understands how the binding occurs can help with this, I'd really appreciate it.

I am fairly new to C# and very ignorant about how objects are bound to controls.

Thanks!!

Someone outside the forum recommended I enable more options in the IDE's Debug/Exceptions setup, so I checked all of them and ran the progam. I'm not sure why these are all unchecked by default, but I'm getting an exception much sooner now.

When this line of code is executed:

data1SourceBindingSource.DataSource = dataMgr.data1Source;

the form begins going through it's binding to object code enumerates through my list. I've implemented the IEnumerable interface, but the binding code seems to still be executing passed the end of my list. I have 30 items in the list and I would expect it to use the MoveNext() method to realize it has reached the end of the list, but it fails accessing my Key property when the dataSrc.data1.index is already equal to the dataSrc.data1.Count .

Have I not implemented the IEnumerable interface correctly? :

public class Data1Source : IEnumerable
    {
        public Data2Source data2Source;
        public Data1 data1;

        public Data1Source(Data1 data1, Data2 data2)
        {
            this.data1 = data1;
            data2Source = new Data2Source(data2);
        }

        public string Key
        {
            get { return data1.Current().key; }
            set { data1.Current().key = value; }
        }
        public Data2Source Data2Source // allows it to show up in Data Sources tab
        {
            get { return data2Source; }
        }

        IEnumerator IEnumerable.GetEnumerator()
        {
            return new Data1SourceEnum(this);
        }
    }

    public class Data1SourceEnum : IEnumerator
    {
        Data1Source dataSrc;

        // Enumerators are positioned before the first element
        // until the first MoveNext() call.
        // int position = -1;

        public Data1SourceEnum(Data1Source dataSrc)
        {
            this.dataSrc = dataSrc;
            dataSrc.data1.index = -1;
        }

        public bool MoveNext()
        {
            dataSrc.data1.index++;
            return (dataSrc.data1.index < dataSrc.data1.Count);
        }

        public void Reset()
        {
            dataSrc.data1.index = -1;
        }

        public object Current
        {
            get
            {
                try
                {
                    return dataSrc;
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
    }

Ok, I think I see what's going on here and it was easy enough to fix the arg out range for Data1Source object. I don't know whether it's a good way or not:

public string Key
        {
            get {
                // allows init to complete until ResetCurrentItem occurs
                if (data1.index < 0 || data1.index >= data1.Count())
                    return string.Empty;

                return data1.Current().key; 
            }
            set {
                if (data1.index < 0 || data1.index >= data1.Count())
                    System.Diagnostics.Debug.Assert(false); // should never happen because item will already exist before user can edit

                data1.Current().key = value;
            }
        }

Not sure yet how I will handle the Data2Source when the list is empty, or why it works when there is one item in the list. And yes, I am enjoying having this conversation with myself...:|

I came down with one hell of a cough so I haven't been online lately :(

Give me a day or two and i'll take a look at it.

Ok I did find a few problems but I am having a hard time understanding your entity relationships here. Do you think you could give me meaningful names and more information on how you want this application to work? First off your form's load event is setting the value of the combo fox, which changes the value changed event, which fires off your databind events, and throws 3 of the handled errors. You should disable the events until the form is loaded.

Next lets examine this class:

public class Data2SourceEnum : IEnumerator
    {
        Data2Source dataSrc;

        // Enumerators are positioned before the first element
        // until the first MoveNext() call.
        //int position = -1;

        public Data2SourceEnum(Data2Source dataSrc)
        {
            this.dataSrc = dataSrc;

            dataSrc.data2.index = -1;
        }

        public bool MoveNext()
        {
            dataSrc.data2.index++;
            return (dataSrc.data2.index < dataSrc.data2.Count);
        }

        public void Reset()
        {
            dataSrc.data2.index = -1;
        }

        public object Current
        {
            get
            {
                try
                {
                    return dataSrc;
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }
    }

The constructor:

public Data2SourceEnum(Data2Source dataSrc)
        {
            this.dataSrc = dataSrc;
            dataSrc.data2.index = -1;
        }

Now current:

public object Current
        {
            get
            {
                try
                {
                    return dataSrc;
                }
                catch (IndexOutOfRangeException)
                {
                    throw new InvalidOperationException();
                }
            }
        }

You return the data source passed in the constructor regardless of the position of the enumerator AND the enumerator should always encapsulate its own index! You don't want another class having r/w access to it.

You also should create your datasources in the constructor of the form instead of the load event. During the Form_Load is when the binding starts and you should have instantiated their storage before then.

Actually I dug down in to it.. there are a lot more problems with the enumerators. Please clarify what you're trying to do :)

Scott, I just wanted to say thanks for taking the time and I hope you feel better soon. I will explain the why's and how's tomorrow as best I can. In the mean time, get some rest and get well my friend.

I came down with one hell of a cough so I haven't been online lately :(

Give me a day or two and i'll take a look at it.

Thanks for you input Scott.

The Data Source Objects (Data1Source and Data2Source in this case) are wrappers around some existing code in an experiment to implement binding of controls to data objects whos relationships are already being managed. This whole endeavor began as I modified the form interface from a very large form, then to two forms (parent/child), then to a tabcontrol design. It was at this point I thought to myself it would be nice if I could wrap the Data Source Object design around each of the data managers along with the Validating and Validated events and then I could just drag these fields onto forms or whatever in the future and not have to do any additional coding to implement the controls or their types.

You return the data source passed in the constructor regardless of the position of the enumerator AND the enumerator should always encapsulate its own index! You don't want another class having r/w access to it.

The index that would normally be encapsulated in the IEnumerator interface is/was already encapsulated in the classes containing the data objects, which is what this simulated implementation represents. I exposed this index for the purpose of this test. Since the MS example implementation of this interface prescribes only the methods needed by the interface, I don't think it should matter where the index is located as long as the implementation is cooperative to prevent conflict. However, I do agree with you in the ideal sense.

I had, seemingly, successfully wrapped this Data Source interface design around these objects and it wasn't until I began adding another table like relationship with new object not yet having any records in it that I ran into this initialization issue. Thus, the question of why this issue occurs only when the list is empty, verses when it has at least one item in the list. This is also why I implemented the IComparer<Data2ListItem> in this simulation so it could show that the data's values where being successfully bound to the controls on Tab2 when there is at least one item in the Data2 List. If you manipulate the combobox item, the implementation will successfully update the controls on the Tab(s) to reflect this change without any additional code by me to cause this behavior.

Having said all that, I could do a number of things, including rewriting all object interfaces (definitly not desirable), creating a temporary record in my new object manager for each primary record as needed since each primary record will be tied to zero-to-many subrecs for this new table like object, or (most desirable) understand why it this "empty list" behavior occurs and handle it gracefully without coding workarounds in the underlying/existing coded objects, which I have not had to do any thus far.

First off your form's load event is setting the value of the combo fox, which changes the value changed event, which fires off your databind events, and throws 3 of the handled errors. You should disable the events until the form is loaded.

I am including a fresh zipped version of the project that contains the changes to the Data Source objects' properties to handle the index out of range during init because I have all of the exception boxes in debug checked and I am not getting any exceptions so long as there is an item in the Data2 list, which I will fill (uncomment) by default in this attachment. If you arrow through the items in the combobox, you will see the controls being updated to reflect the change as directed by call to data1SourceBindingSource.ResetCurrentItem(); .

I still don't understand why your Current property always returns the same instance

public object Current
        {
          get
          {
            try
            {
              return dataSrc;
              //return dataSrc.data1[index]; ???
            }
            catch (IndexOutOfRangeException)
            {
              throw new InvalidOperationException();
            }
          }
        }

To be honest I don't know that I can help you much. I don't understand the entity relationship and they don't have meaningful names and the way things are implemented.... it makes it a little hard to follow the code. :(

I still don't understand why your Current property always returns the same instance

public object Current
        {
          get
          {
            try
            {
              return dataSrc;
              //return dataSrc.data1[index]; ???
            }
            catch (IndexOutOfRangeException)
            {
              throw new InvalidOperationException();
            }
          }
        }

To be honest I don't know that I can help you much. I don't understand the entity relationship and they don't have meaningful names and the way things are implemented.... it makes it a little hard to follow the code. :(

It doesn't access it directly because I allowed the properties to handle the index out of range during initialization. I don't know why, but during intialization the binding methods will attempt to access the property accessor after it has moved through the list (builds its own list) but without resetting Reset() and MoveNext() or something. This exception doesn't appear until I turned on all the exception options in the debug Exceptions menu. I'm not sure exactly how MS intended this to be handled when binding to a Data Source Object (wizard function) and I wouldn't have gotten this far had I had seen it was doing this in the beginning. I'm going to start up the bigger application with these extended exceptions turned on (scary man) and see what happens because I haven't done that yet...:scared:

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.