Hi,
We have a WinForm which has a WinGrid binding to a BindingSource with DataSource set to a TypeSafe BindingList.
A background process will update this BindingList periodically by calling the BindingList's SetItem or Add method.
However, on occasion, we encountered the following exception:
<ExceptionType>System.InvalidOperationException, mscorlib, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</ExceptionType> <Message>BindingSource cannot be its own data source. Do not set the DataSource and DataMember properties to values that refer back to BindingSource.</Message> <Source>System.Windows.Forms</Source> <HelpLink /> <Property name="Data">System.Collections.ListDictionaryInternal</Property> <Property name="TargetSite">Int32 get_Count()</Property> <StackTrace> at System.Windows.Forms.BindingSource.get_Count() at System.Windows.Forms.CurrencyManager.List_ListChanged(Object sender, ListChangedEventArgs e) at System.ComponentModel.ListChangedEventHandler.Invoke(Object sender, ListChangedEventArgs e) at System.Windows.Forms.BindingSource.OnListChanged(ListChangedEventArgs e) at System.Windows.Forms.BindingSource.InnerList_ListChanged(Object sender, ListChangedEventArgs e) at System.ComponentModel.BindingList`1.OnListChanged(ListChangedEventArgs e) at System.ComponentModel.BindingList`1.SetItem(Int32 index, T item)...
Although I don't think WinGrid would be the cause of this exception, I would like to know if there is anything that I might be doing wrong which caused this problem...
Any help would be appreciated.
Thanks.
Kai
In my application I saw that if I update the list, it calls OnListChanged and changes the control, so threading is obviously a problem.
To solve that I created a thread-safe bindingsource which is a custom control that inherits BindingSource:
public partial class MyBindingSource : BindingSource
{
InitializeComponent();
}
private static extern IntPtr GetForegroundWindow();
/// <summary>
/// Pass the call the the main thread for windows forms
/// </summary>
/// <param name="e"></param>
var control = Control.FromHandle(handle);
control.Invoke(new Action<ListChangedEventArgs>(OnListChanged), e);
else
Hi Kai,
You have to be very careful when using multiple threads. It is your responsibilty to make sure that nothing that happens on the background thread directly calls any methods on the UI thread without the proper marshalling. What you are doing here will almost certainly cause a problem because your data source will fire notifications that the data has changed on the background thread and the grid will respond to these notifications on the UI Thread. So this will not work.
I recommend that you check out the Microsoft documentation on threading. Start with the InvokeRequired, BeginInvoke, and Invoke methods.