bindingsource datagridview dataerror

P

paul

I have a simple test form (C# 2.0) that has a DataGridView bound via a
BindingSource to a strongly typed DataSet.DataTable which is a property
of a business class.

The Grid is bound to the datasource at design time and the
BindingSource.DataSource is set at runtime in the form constructor and
is not changed again (by my code anyhow!).

The business class has a background worker that has a loop that uses a
thread pool (Wintellect PowerThreading) to update a column value in
random rows (this is only for testing).

It's all fairly straightfoward and generally works ok with the form
showing the rows being updated as expected.

However, I frequently get the following error which is caught in
DataGridView.DataError event:

System.InvalidOperationException: BindingSource cannot be its own data
source. Do not set the DataSource and DataMember properties to values
that refer back to BindingSource.
at System.Windows.Forms.BindingSource.get_Count()
at System.Windows.Forms.CurrencyManager.get_Item(Int32 index)
at
System.Windows.Forms.DataGridView.DataGridViewDataConnection.GetError(Int32
boundColumnIndex, Int32 columnIndex, Int32 rowIndex)


The thing is I don't change the BindingSource or DataGridView after its
initial setting.

I've logged the event using log4net and tried to come up with a common
cause but no obvious bug is apparent.

Any ideas whats going on here?

TIA

Paul

Source

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

using log4net;

using ThreadDataTable;

namespace ThreadDataTableTester
{
public partial class Form1 : Form
{
private static ILog logger = LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType );

TestProcess p = new TestProcess();

public Form1()
{
InitializeComponent();
this.testDataDataTableBindingSource.DataSource =
p.TestData.TestData;
}

private void checkBox1_CheckedChanged( object sender, EventArgs
e )
{
if ( checkBox1.Checked )
{
p.Start();
}
else
{
p.Stop();
}
}

private void exitToolStripMenuItem1_Click( object sender,
EventArgs e )
{
this.Close();
}

private void dataGridView1_DataError( object sender,
DataGridViewDataErrorEventArgs e )
{
//dataGridView1[ e.ColumnIndex, e.RowIndex
].Style.BackColor = System.Drawing.Color.Red;
logger.Error( string.Format( "GridView error {0}/{1} -
{2}", e.RowIndex, e.ColumnIndex, e.Exception ) );
}

private void testDataDataTableBindingSource_DataError( object
sender, BindingManagerDataErrorEventArgs e )
{
logger.Error( string.Format( "Binding Source error {0}",
e.Exception ) );
}

private void testDataDataTableBindingSource_CurrentChanged(
object sender, EventArgs e )
{
//logger.Info( string.Format( "Binding source position
changed {0}", testDataDataTableBindingSource.Position ) );
}


}
}

Business Class:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.ComponentModel;
using System.IO;

using log4net;
using Wintellect.Threading.ThreadPool;

namespace ThreadDataTable
{
public class TestProcess
{
private static ILog logger = LogManager.GetLogger(
System.Reflection.MethodBase.GetCurrentMethod().DeclaringType );

private CallbackThreadPool tp = new CallbackThreadPool( 1000,
20, 2 );
private TestDataSet m_TestData = new TestDataSet();
private bool doStuff = false;
private BackgroundWorker bw = new BackgroundWorker();
private Random keyRec = new Random();
Random someValue = new Random();

public TestDataSet TestData
{
get { return this.m_TestData; }
set { this.m_TestData = value; }
}

public bool DoStuff
{
get { return this.doStuff; }
set { this.doStuff = value; }
}

public TestProcess()
{
//tp.ThreadEvent += new
EventHandler<CallbackThreadPoolEventArgs>( tp_ThreadEvent );

for ( int i=0; i < 50; i++ )
{
TestDataSet.TestDataRow row =
m_TestData.TestData.NewTestDataRow();
row.key = i;
row.someMore = someValue.Next( 10000 );
row.data = "orig " + row.someMore;
m_TestData.TestData.Rows.Add( row );
}

bw.DoWork += new DoWorkEventHandler( bw_DoWork );
bw.RunWorkerCompleted += new
RunWorkerCompletedEventHandler( bw_RunWorkerCompleted );
}

private void bw_DoWork( object sender, DoWorkEventArgs e )
{
doStuff = true;

do
{
int updatekey;
lock ( keyRec )
{
updatekey = keyRec.Next( 50 );
}

tp.QueueUserWorkItem( UpdateRow, updatekey );

} while ( doStuff );
}

private void UpdateRow( object o )
{
int key = (int)o;
logger.Info( string.Format( "{0} processing", key ) );

try
{
lock ( m_TestData.TestData )
{
TestDataSet.TestDataRow row =
m_TestData.TestData.FindBykey( key );
if ( row != null )
{
row.BeginEdit();
lock ( someValue )
{
row.someMore = someValue.Next( 10000 );
}

row.updateCount++;
row.EndEdit();
row.AcceptChanges();

TextWriter tw = new StreamWriter(
string.Format( @"c:\logs\threadtable\{0}.txt",key) );
tw.WriteLine( string.Format(
"{0},{1},{2},{3},{4}",
row.key,
row.data,
row.someMore,
row.updateCount,
DateTime.Now ) );
tw.Close();
System.Threading.Thread.Sleep( 10 );
logger.Info( string.Format( "{0} - {1} updated
to {2}", key, row.updateCount, row.someMore ) );
}
else
{
logger.Info( string.Format( "{0} no row found",
key ) );
}
}

}
catch ( Exception ex )
{
logger.Error( string.Format( "{0} Update Error {1}",
key, ex.ToString() ) );
}
}


private void bw_RunWorkerCompleted( object sender,
RunWorkerCompletedEventArgs e )
{
logger.Info( string.Format( "BW Complete" ) );
}

private void tp_ThreadEvent( object sender,
CallbackThreadPoolEventArgs e )
{
logger.Info( string.Format( "Thread Pool {0}", e.Reason )
);
}

public void Start()
{
bw.RunWorkerAsync();
}

public void Stop()
{
doStuff = false;
}




}
}
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top