3
votes

Hi im learning about MVVM and Win8 app development, and Im having trouble with binding an ObservableCollection (located in NoteViewModel.cs) to my MainPage listbox (or listview) through XAML.

public ObservableCollection<Note> NotesList;

The Model is a simple Note.cs class, which holds NoteText, Priority and RemindDate.

What Im doing right now is set the DataContext in the code-behind file of MainPage.xaml.cs to the ObservableCollection.

public MainPage()
{
    this.InitializeComponent();
    NoteViewModel nvm = new NoteViewModel();
    noteListView.DataContext = nvm.NotesList;
}

And in the NoteViewModel Constructor I simply create 2 new Notes which I then add to the Collection.

What I would like to do is set the DataContext in XAML to the NoteViewModel and the ItemsSource to the NotesList. I want to implement a DetailsView to a single note later.

There are lots of tutorial with binding collections to listboxes, but I havent found one which shows the MVVM-correct way to do so.

Any help?

3

3 Answers

3
votes

You need to bind your View (MainPage) to your ViewModel, rather than setting the DataContext of your list to the collection

Then in your view's xaml, you bind the list's ItemSource to your ViewModels NotesList property

E.G.

ViewModel:

public NoteViewModel : INotifyPropertyChanged
{
  //Collection must be a property
  public ObservableCollection<Note> NotesList {get; private set;}

  public NoteViewModel()
  {
     //Initialize your collection in the constructor
     NotesList = new ObservableCollection<Note>()
  }

  //.
  //.
  //.

}

You can still set the DataContext in code behind if you wish

public MainPage()
{
  this.InitializeComponent();
  NoteViewModel nvm = new NoteViewModel();
  this.DataContext = nvm;
}

Alternatively you can set the DataContext via your View's xaml. Assuming your ViewModel is in the namespace MyProject:

Add a reference to your namespace

<UserControl x:class=MyProject.MainPage
  xmlns:local="clr-namespace:MyProject"
  .
  .
>

Add the ViewModel as a resource

<UserControl.Resources>
  <local:NoteViewModel x:Key="NoteViewModel"/>
</UserControl.Resources>

Bind your main container's DataContext to this resource

<Grid x:Name="LayoutRoot" DataContext="{StaticResource NoteViewModel}">

After you have set the DataContext, you then need to set the ItemSource for the notesListView control via a binding

ItemSource={Binding NotesList}
1
votes

For a simple test case scenario, try this:

Create your ViewModel:

 // Create a property as an ObservableCollection<YourType> LstItemName in your ViewModel
 // On your ViewModel constructor, create a new LstItemName instance.
 // Create a property as "YourType" ItemName to bind to the selected Item of your List

Create your View:

 // Create a property of your ViewModel (codeBehind)
 // On your Views Constructor, create a new ViewModel instance. (codeBehind)
 // On loaded event of your View set the DataContext = ViewModel (codeBehind)

On your XAML at your List:

<List     
ItemSource={Binding LstItemName}
SelectedItem={Binding ItemName}
/>

Remember to add list Items using your ViewModel.

0
votes

For nice effortless mvvm try learning some library that enforces it I use caliburn micro. It is easy to setup and provides many very useful components.