Ok, this has been a head scratcher for me. I have a ListBox I am binding to a linq query like so:
private IQueryable<Feed> _feeds;
public IQueryable<Feed> Feeds
{
get
{
if (_feeds == null)
{
var feedsQuery = from f in _db.Feed orderby f.Title select f;
_feeds = feedsQuery;
}
return _feeds;
}
}
public Options()
{
InitializeComponent();
this.DataContext = Feeds;
}
(For the record I've also tried List, instead of IQueryable)
Everything shows up great and I have a databound form that allows you to edit a record and all of those changes work just fine, the modified data shows up in the list.
The problem comes with I add an item. Nothing shows up in the list. The data goes into the database fine, but the only way to see the data is closing and restarting my app. I'm using the code below as an example:
Feed feed = new Feed()
{
ID = Guid.NewGuid(),
Url = "http://www.test.com",
Title = "Test"
};
_db.Feed.InsertOnSubmit(feed);
_db.SubmitChanges();
_db.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues);
(with or without the _db.Refresh nothing happens)
What's going on?
Unless notified otherwise, the
ListBox
only iterates once over itsItemsSource
. Your query is only being run once.The query object doesn't know when the database changes (and
Refresh
doesn't help; see below)--it's up to you to know (or anticipate) that and to rerun relevant queries at the appropriate times.Stan R mentions
ObservableCollection
. That's fine, but simply storing the result of your query in anObservableCollection
won't solve the problem unless you do some work to update the collection yourself when the database changes. This means rerunning the query and manually adding new items and removing deleted items from the collection. (You could alternatively just rerun the query and set the entire result back in to the ListBox, but that means a whole new set of items will be created--not very performant, and maybe not what you want for other reasons.)As an aside, your call to
DataContext.Refresh
is probably not doing what you think it is. From the docs:Okay. I'm not positive this is 100% the correct way to use the ObservableCollection, but this seems to work:
And add my item:
It took me a little while to figure out I had to update the list manually (thanks Ben), but it all seems to work. Sorting would be nice, but I'll worry about that another time.
You are doing everything right, you jus need to use ObservableCollection. This will notify the ListBox about any changes in the list and refresh it automatically.
From MSDN
P.S. you don't need a db refresh