0

Excuse me but I didn't know how to formulate the question :

I have two ObservableCollection

ObservableCollection MyMainList is the ObservableCollection where are stored all of my objects.

ObservableCollection<T> MyFilteredList = new ObservableCollection(MyMainList.Where(x=>Condition))

is the ObservableCollection filtered according some parameters.

At one moment, I need to add or remove objects from MyMainList, but then MyFilteredList is not updated automatically.

I need always to do :

MyMainList.Add(newObject);
MyFilteredList.Add(newObject);

Is there a way to do all of that in just one line, so when I modify MyMainList, MyFilteredList will be automatically updated?

Edit : To answer to Adriano Repetti, when I open my window, I load all of objects (so I don't need to reload my DB everytime I change filters). I have three different filters : - 1 combobox "Affaire" (list of the contracts) - 1 combobox "Phase" (list of the subcontracts) - 1 TextBox "Filter" ( if I want to see only objects whose name contains that text).

When I change selection of 1st ComboBox, I update the list of subcontracts, and update the filtered list of assemblies.

private Affaire selectedAffaire;
public Affaire SelectedAffaire
{
   get { return selectedAffaire; }
   set
   {
      selectedAffaire = value;
      this.NotifyPropertyChanged("SelectedAffaire");
      if (value != null)
      {
         GetListPhaseInContract(); //I update the list of subcontracts in 2nd Combobox
      }
      UpdateListAssemblages(); // I update MyFilteredList
   }
}

When I change selection of 2nd ComboBox (subcontract), I update the list of MyFilteredList

private Phase selectedPhase;
public Phase SelectedPhase
{
   get { return selectedPhase; }
   set
   {
       selectedPhase = value;
       this.NotifyPropertyChanged("SelectedPhase");
       UpdateListAssemblages();
   }
}

Then when I change my TextBox value, I also update the list

private string texteFiltre;
public string TexteFiltre
{
   get { return texteFiltre; }
   set
   {
      texteFiltre = value;
      this.NotifyPropertyChanged("TexteFiltre");
      UpdateListAssemblages();
   }
}

If I understood, this post is what I need to look for? I don't know yet what are ICollectionView, but I guess I need to look in that way?Will I gain some execution time using ICollectionView? as I see I need anyway to Refresh it?

Siegfried.V
  • 1,508
  • 1
  • 16
  • 34
  • 1
    I don't know what your design is but in this case I'd avoid to have a **copy** of your data, as you can see it's hard to keep them in sync. What I'd use is a **view** of the observable collection (which might be smart enough to fire the appropriate events or a dumb view which always fires `Reset`). – Adriano Repetti Jan 23 '19 at 18:26
  • @AdrianoRepetti yes in fact I think I am doing something wrong (I am new with MVVM concept). Could you please explain me how I can define these filtered views? Because in that case it is pretty simple, but sometimes I have a view that is a filter of a collectionview, and conditions are on selected elements of a second view. I will now edit my post to put some more concrete code(and I am aware I am doing something wrong). – Siegfried.V Jan 23 '19 at 19:13
  • 1
    You can have multiple views based on one collection and filters can be as complicated as you like so long as they return a bool for any given record. https://social.technet.microsoft.com/wiki/contents/articles/26673.wpf-collectionview-tips.aspx – Andy Jan 23 '19 at 20:03
  • Take a look at [DynamicData](https://dynamic-data.org/), it is far more powerfull than Views of observable collections – Krzysztof Skowronek Jan 23 '19 at 20:11
  • Very similar question asked and answered [here](https://stackoverflow.com/questions/1256793/mvvm-sync-collections). That case involves synching two different types of collections, your scenario is more simple. – Mark Feldman Jan 23 '19 at 21:01
  • Ok thanks all for your answers, I definitely will look further in documentations, until now I didn't use them(cause I didn't manage to use them), but I see this will be very helpful. – Siegfried.V Jan 24 '19 at 03:16
  • @AdrianoRepetti thanks, I made a tutorial (www.blackwasp.co.uk) and finally understood all about 'ICollectionView' – Siegfried.V Jan 25 '19 at 06:22

1 Answers1

1

Since you didn't give us the detial of the data struct, I just assume that PhaseInContract is included in MainList. So, just simply create two views for your MainList, then binding them to UI. All views will synchronize with source automatically.

Public ICollectionView MainListView;
Public ICollectionView PhaseInContractView;
Public ObservableCollection<YourDataClass> MainList;

public YourViewModel()
{
    MainList = new ObservableCollection<YourDataClass>();

    // Load datas form db and fill MainList

    MainListView = new CollectionViewSource() { Source = MainList }.View;
    MainListView.Filter = (x) =>
    {
        // your MainListView filtering logic.
    };

    PhaseInContractView = new CollectionViewSource() { Source = MainList }.View;
    PhaseInContractView.Filter = (x) =>
    {
        // your PhaseInContractView filtering logic
    };

private Affaire selectedAffaire;
public Affaire SelectedAffaire
{
    get { return selectedAffaire; }
    set
    {
        selectedAffaire = value;
        this.NotifyPropertyChanged("SelectedAffaire");
        if (value != null)
        {
           PhaseInContractView.Refresh();
        }
        MainListView.Refresh();
    }
}

// And other properties.
...
Alex.Wei
  • 1,798
  • 6
  • 12
  • in fact I made the tutorial on ICollectionView (www.blackwasp.co.uk), and that helped solving my problem, need to update all of my project with these views, very useful. Thanks – Siegfried.V Jan 25 '19 at 06:23