tags:

views:

649

answers:

3

Hi all,

I've defined the following view:

<CollectionViewSource x:Key="PatientsView" Source="{Binding Source={x:Static Application.Current}, Path=Patients}"/>

Where Patient is the following property:

public IEnumerable<Patient> Patients
{
 get
 {
  return from patient in Database.Patients
      orderby patient.Lastname
      select patient;
 }
}

Somewhere in my code, I change the Patients database, and I want to have the controls that display this data (using the "PatientsView") to be automatically notified. What's a proper way to do this? Can the CollectionViewSource be invalidated or something?

A: 

Table<T> does not support IListChanged events, you will have to do this yourself (I had to do the same earlier today).

leppie
+1  A: 

How to invalidate a CollectionViewSource in code behind:

CollectionViewSource patientsView = FindResource("PatientsView") as CollectionViewSource;
patientsView.View.Refresh();
Wallstreet Programmer
I've tried this code. Nothing happens when refresh is called! I set a breakpoint on my Patients property: it is not called when Refresh() is called..
Robbert Dam
A: 

I think this is a bit more complex than it seems. Notifying your client application about changes in database is a non-trivial task. But your life is easier if the database is changed only from your application - this makes you able to put "refreshing logic" whenever you change the database.

Your "Patients" property seems to be present in one class (maybe a little more than one? :) ). And you probably bind some ListBox to the CollectionViewSource. So instead of calling Refresh on the CollectionViewSource you can make WPF re-call the getter. For this the class that has Patients property has to implement INotifyPropertyChanged interface.

The code would look like this:

public class TheClass : INotifyPropertyChanged
{
public IEnumerable<Patient> Patients
  {
    get
    {
            return from patient in Database.Patients
                   orderby patient.Lastname
                   select patient;
    }
  }

#region INotifyPropertyChanged members
// Generated code here
#endregion

public void PatientsUpdated()
{
  if (PropertyChanged != null)
    PropertyChanged(this, "Patients");
}
}

Now, call PatientsUpdated() on an instance of TheClass to trigger update of the binding.

P.S. Having said all that it just feels like a bad design somehow.

arconaut
All my changes are done locally in the application, so I can add the refresh logic. However, calling Refresh() has no effect!
Robbert Dam
I've modified my post with some more thoughts.
arconaut
This is it. Still don't know why Refresh() does not work, but this works fine! Thanks
Robbert Dam