Well, it works. Not sure about design quality, but it was better than the hacks I was using before. Thanks for all the help! Let me know if it sucks. Here's a sample which demonstrates the pattern; first the caller/form:
using System;
using System.Windows.Forms;
using GrowingDataTable;
namespace dgv
{
public partial class Form1 : Form
{
public DataGridView dgvMain;
public delegate void delEventHandler(object sender,
GrowingDataTable.UpdateDataTableOnYourThreadContextEventArgs e);
public GrowingDataTable gt;
public Form1()
{
InitializeComponent();
}
private void Form1\_Load(object sender, EventArgs e)
{
// add a datagridview to the form
dgvMain = new DataGridView();
Controls.Add(dgvMain);
dgvMain.Dock = System.Windows.Forms.DockStyle.Fill;
// create the GrowingTable object
gt = new GrowingDataTable();
// subscribe to the GrowingTable event
gt.RaiseUpdateTableAgainstYourThreadContextEvent += new
EventHandler<GrowingDataTable.UpdateDataTableOnYourThreadContextEventArgs>
(gt\_RaiseUpdateTableAgainstYourThreadContextEvent);
// tell gt that we want to be updated
gt.UpdateDataTableOnCallerThreadContext = true;
// assign the DataTable as DataSource for our datagridview
dgvMain.DataSource = gt.itemTable;
// tell the GrowingTable to start growing;
// delay start for 3 seconds, add row every 1 second
gt.Start(3000, 1000);
}
void gt\_RaiseUpdateTableAgainstYourThreadContextEvent(object sender,
GrowingDataTable.UpdateDataTableOnYourThreadContextEventArgs e)
{
if (InvokeRequired) {
Invoke(new
delEventHandler(gt\_RaiseUpdateTableAgainstYourThreadContextEvent),
new object\[\] { sender, e}); }
else
{
if ((e.Updates != null) || (e.Updates.Count > 0))
{
gt.UpdateTableOnMyThreadContext(e.Updates);
}
}
}
}
}
Then the library class GrowingDataTable:
using System;
using System.Collections.Concurrent;
namespace GrowingDataTable
{
public class GrowingDataTable
{
public System.Data.DataTable item