views:

46

answers:

1

Hello;

today I examinted WAP from codeplex a bit and saw this:

BookListView.xaml:

<ListView ItemsSource="{Binding Books}" SelectedItem="{Binding SelectedBook}" 
                  SelectionChanged="ListViewSelectionChanged">
            <ListView.View>
                <GridView>
                    <GridViewColumn DisplayMemberBinding="{Binding Title}" Header="{x:Static p:Resources.Title}" Width="250"/>
                    <GridViewColumn DisplayMemberBinding="{Binding Author}" Header="{x:Static p:Resources.Author}" Width="150"/>
                    <GridViewColumn DisplayMemberBinding="{Binding PublishDate, StringFormat=d}" Header="{x:Static p:Resources.PublishDate}" Width="100"/>
                </GridView>
            </ListView.View>

UPDATE:

[Export(typeof(IBookListView))]
    public partial class BookListView : UserControl, IBookListView
        {
            public BookListView()
            {
            InitializeComponent();
        }


        private BookListViewModel ViewModel { get { return DataContext as BookListViewModel; } }


        private void ListViewSelectionChanged(object sender, SelectionChangedEventArgs e)
        {
            foreach (Book book in e.RemovedItems)
            {
                ViewModel.SelectedBooks.Remove(book);
            }
            foreach (Book book in e.AddedItems)
            {
                ViewModel.SelectedBooks.Add(book);
            }
        }
    }

public class BookListViewModel : ViewModel<IBookListView>
    {
        private readonly IEnumerable<Book> books;
        private readonly ObservableCollection<Book> selectedBooks;
        private Book selectedBook;
        private ICommand addNewCommand;
        private ICommand removeCommand;


        public BookListViewModel(IBookListView view, IEnumerable<Book> books)
            : base(view)
        {
            if (books == null) { throw new ArgumentNullException("books"); }

            this.books = books;
            this.selectedBooks = new ObservableCollection<Book>();
        }


        public IEnumerable<Book> Books { get { return books; } }

        public ObservableCollection<Book> SelectedBooks
        {
            get { return selectedBooks; }
        }

        public Book SelectedBook
        {
            get { return selectedBook; }
            set
            {
                if (selectedBook != value)
                {
                    selectedBook = value;
                    RaisePropertyChanged("SelectedBook");
                }
            }
        }

        public ICommand AddNewCommand
        {
            get { return addNewCommand; }
            set
            {
                if (addNewCommand != value)
                {
                    addNewCommand = value;
                    RaisePropertyChanged("AddNewCommand");
                }
            }
        }

        public ICommand RemoveCommand
        {
            get { return removeCommand; }
            set
            {
                if (removeCommand != value)
                {
                    removeCommand = value;
                    RaisePropertyChanged("RemoveCommand");
                }
            }
        }
    }

BookController: Here the books are fetched from Entity Framework/database

public void Initialize()
        {
            bookViewModel.LendToCommand = lendToCommand;
            bookViewModel.PropertyChanged += BookViewModelPropertyChanged;

            IBookListView bookListView = container.GetExportedValue<IBookListView>();
            bookListViewModel = new BookListViewModel(bookListView, entityService.Books);
            bookListViewModel.AddNewCommand = addNewCommand;
            bookListViewModel.RemoveCommand = removeCommand;
            bookListViewModel.PropertyChanged += BookListViewModelPropertyChanged;

            shellViewModel.BookListView = bookListViewModel.View;
            shellViewModel.BookView = bookViewModel.View;

            bookListViewModel.SelectedBook = bookListViewModel.Books.FirstOrDefault();
        }

and exactly those books are passed bookListViewModel = new BookListViewModel(bookListView, entityService.Books); to the BookListViewModel which is set as DataContext of the BookListView.xaml binding to books.

I was shocked!!! Am I right that they directly bind to the models properties?

A: 

It is perfectly legitimate to bind directly to the model via a property on the ViewModel.

You would only have to reimplement a property on the ViewModel if it required processing for the View, otherwise it is your choice.

Take a look at this for Karl Shifflet's take on MVVM application layers.

benPearce
@benPearce They do not delegate to the books collection they bind directly to it! Every model object must be wrapped in MVVM pattern and those books are a collection of type book so there must be a bookViewModel wrapping a book. But there is nothing.
Lisa
Karl Shifflet is taking MVVM not that serious. That are even his words not literally of course...
Lisa
above all this code from WAF is a joke:passing data from the view to the viewodel ??? Getting the selectedBooks could easily be done with a SelectedItems behaviour bound to the viewmodel. private void ListViewSelectionChanged(object sender, SelectionChangedEventArgs e) { foreach (Book book in e.RemovedItems) { ViewModel.SelectedBooks.Remove(book); } foreach (Book book in e.AddedItems) { ViewModel.SelectedBooks.Add(book); } }
Lisa