views:

591

answers:

1

I have a ModelView with multiple ObservableCollection. Is this the right approach and also when ever view calls the view modle, all the ObservableCollection needs to be re-populated with data and then binding takes place again for all the CollectionViewSource.

Also how do I call CollectionViewSource.GetDefaultView outside the constructor of the viewmodel, i get an error that it can only be called in the construtor.

If I create a seperate ModelView for each of the CollectionViewSource, then while binding one of the view with ModelView, rest of the controls also gets binded buth this time with null values and all all the ModelView is not called.

I am really confused what to do, please help.

A: 

It sounds like you're using MVVM. You can certainly bind to multiple ObservableCollections. The question really is: do you need to? You should reserve binding to ObserableCollections for cases where your ViewModel is changing and you need to keep your View updated with the changes.

Here's an example I whipped up for you of a View bound to two ObservableCollections and one List in a ViewModel. So -- yes -- you can certainly bind to whatever you want. In this example, the two ObservableCollections will alternate updating. Does that help?

I posted the code for this here if it helps to have the whole vs project.

View:

<Window x:Class="WpfApplication1.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <StackPanel Orientation="Vertical">

     <TextBlock>Bind to List:</TextBlock>
     <ListView ItemsSource="{Binding Path=Users}" Height="20"/>

     <TextBlock>Bind to ObservableCollection1:</TextBlock>
     <ListView ItemsSource="{Binding Path=ObservableCollection1}" 
                 Height="100"/>

     <TextBlock>Bind to ObservableCollection2:</TextBlock>
     <ListView ItemsSource="{Binding Path=ObservableCollection2}" 
                 Height="100"/>

    </StackPanel>
</Window>

ViewModel (View is bound to this ViewModel)

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Timers;
using System.Windows;
using System.Windows.Threading;
namespace WpfApplication1
{
  public class Class1
  {
    public List<string> Users{get;set;}
    public ObservableCollection<string> ObservableCollection1 { get; set; }
    public ObservableCollection<string> ObservableCollection2 { get; set; }
    public Class1()
    {
      this.Users = new List<string>{ "bob", "mary" };

      this.ObservableCollection1 = new ObservableCollection<string>();
      this.ObservableCollection2 = new ObservableCollection<string>();
      int counter = 0;
      Timer t1 = new Timer();
      t1.Enabled = true;
      t1.Interval = 1000;
      t1.Elapsed += delegate
      {
        Application.Current.Dispatcher.Invoke(
        DispatcherPriority.Send, new Action(delegate
        {
          if(counter % 2 == 1)
            this.ObservableCollection1.Add(DateTime.Now.ToString());
          else
            this.ObservableCollection2.Add(DateTime.Now.ToString());
          ++counter;
        }));
      };
    }
  }
}
Jeffrey Knight