1
votes

I'm finally getting around to learning about the BindingSource object -- good stuff. So, this type of code is a common way to load a DataGridView now:

    DataTable dtInv = new DataTable();
    // Do whatever populates dtinv...
    bsData.DataSource = null;
    bsData.DataSource = dtInv;
    dgv.DataSource = bsData;

Works fine, and I am able to access the BindingSource's DataRowViews as well as the DataRows underlying those. Cool.

I am wondering about the scope of the underlying DataTable object, though. I used to have dtInv declared as a form-level data member, so I expected everything to work fine when the data behind the BindingSource was accessed from other methods. But it works even when the underlying DataTable is local only to the data-loading method.

So, does a BindingSource object clone the entire DataTable? If I do use a form-level data member for the DataTable, will the BindingSource use a reference to it instead of creating a separate copy of the data? I think I have tested that but am not sure of the results... When I use a form-level DataTable, if I clear/null it out while the Binding ource is displaying its data in the grid, I'll get a null exception if I try to access a DataRow underlying one of the BindingSource's DataRowView objects.

I can't seem to find a definitive answer on this (feel free to point me somewhere that explains this in detail), but the following seems to be the case:

  • If a BindingSource has its DataSource property set to a object that subsequently goes out of scope, the BindingSource keeps the underlying object "alive", accessible, and in its entirety.
  • If the BindingSource has its DataSource property set to an object that remains in scope, it will keep pointing to that as long as it can.

Or, to put it another way, a BindingSource will pull in and keep its underlying data persistent if it needs to (e.g. the underlying object is destroyed/disposed/goes out of scope).

Yes? No? Like I said, I'd appreciate someone "teaching me how to fish" on this one, I just haven't been able to find a discussion about it (or don't know where to read more deeply about it to find one).

1
It's holding a reference to dtInv so it will keep dtInv alive even when the variable dtInv goes out of scope. This isn't anything magic. This is exactly that same as if you'd assign dtInv to a class property or field. - Matt Burland
Thanks, Matt! I guess I didn't fully comprehend the "keep alive" nature of references (well, except when automating an instance of Excel -- I know how things stay "alive" far too well...) As a "best practice", then, do folks usually let the BindingSource or DataGridView keep data persistent, or it is a better idea to keep the underlying DataTable variable in scope as a form class level data member or property? (Feel free to submit your comment as an answer, by the way...) - sutekh137

1 Answers

1
votes

The DataSource is holding a reference to the same object as dtInv, so even though the variable dtInv goes out of scope, the object that it was referencing will not be GC'ed because the DataSource still has a reference to it (of course, when the DataSource goes out of scope, and assuming nothing else is referencing it, then it will become GC eligible). So the object is essentially kept alive. The DataSource is not cloning or copying the object you have it.

As a "best practice", then, do folks usually let the BindingSource or DataGridView keep data persistent, or it is a better idea to keep the underlying DataTable variable in scope as a form class level data member or property?

I assume by "persistent" you mean keep alive in memory rather than what people usually mean by "persistent" data (which usually means saving it somewhere, like a file or a database). What would be considered "best" here depends a lot on what you are doing with the data and whether or not you need to access it again. If you are just grabbing a bunch of data and throwing it read-only into a data grid, then there would be nothing wrong with just setting DataSource and leaving it at that. If you do need to still be able to access that object and do stuff with it (save it back to a database after being edited, for example), I would probably save it as a typed class variable if for no other reason than the type of DataSource is object and you'd have to keep casting it back to whatever it really is when you want to use it.