I have a gridview with the datasource set to a bindinglist. My goal is for the gridview to accurately reflect changes in the bindinglist’s composition (specifically additions at this point). When I add objects to the bindinglist I get an error saying “Bounds cannot be changed while locked”. I believe this is an issue with the Gridview because if I do not set the datasource, the bindinglist is populated as expected. After a lot of searching I came across a few other posts which were similar to my situation:
- Updating Problem -http://www.telerik.com/community/forums/winforms/gridview/updating-problem.aspx
- Updating bindinglist from seperate thread -http://www.telerik.com/community/forums/winforms/gridview/updating-bindinglist-from-seperate-thread.aspx
However these deal with updating data already present in the bindinglist. My application starts with an empty bindinglist set as the datasource and is populated through code.
My C# .Net 3.5 winforms program uses multiple threads to search through all the directories on the machine and return files that meet certain criteria. The recursive search creates a new thread for each directory found to iterate over it's files:
private
static
void
IndexDirectory(
string
directory)
{
foreach
(
string
d
in
Directory.GetDirectories(directory))
{
try
{
Thread t =
new
Thread(
new
ParameterizedThreadStart(GetFiles));
t.Start(d);
IndexDirectory(d);
}
catch
(System.UnauthorizedAccessException){ }
}
}
These files are used to create objects which are stored in a custom collection object which inherits from System.Collections.ObjectModel.Collection<T>. I’ve created an event that fires when an object is added to the collection and subscribe to it in my form. The arguments for the event include the object being added to the collection, so in the event handler I add the object to the bindinglist:
//form field variable used as the datasource for the gridview.
BindingList<MyFileObj> bindingList =
new
BindingList<MyFileObj>();
MyCollectionChangedEventHandler(MyEventArgs e)
{
bindingList.Add( (MyFileObj) e.GetMyFileObj);
}
When that didn’t work I modified the program to use a backgroundworker and queue hoping that putting the code in the WorkerCompleted method would force it to all execute on the UI thread:
Queue<MyFileObj> addMe =
new
Queue<MyFileObj>();
MyCollectionChangedEventHandler(MyEventArgs e)
{
addMe.Enqueue ( (MyFileObj) e.GetMyFileObj);
if
(!backgroundworker.IsBusy)
backgroundworker.RunWorkerAsync ();
}
backgroundworker_DoWork(
object
sender, DoWorkEventArgs e)
{
Try{
e.Result = (MyFileObj) addMe.Dequeue();
}Catch()
{
//queue empty
}
}
backgroundworker_RunWorkerCompleted(
object
sender, RunWorkerCompletedEventArgs e)
{
bindingList.Add((MyFileObj) e.Result);
}
Both of these methods of updating the bindinglist result in the same error.
How can I get my changes to the bindinglist to not crash my program when it is set as a datasource? Preferably, without sacrificing the speed gained through multithreading.
Thanks for any help you can provide.