mplementação do @WPF MVVM INotifyPropertyChanged - Model ou ViewModel

Li vários debates sobre onde implementar INotifyPropertyChanged aqui no StackOverflow e em outros blogs, mas parece que há casos em que você precisa implementá-lo no modelo. Aqui está o meu cenário - estou procurando feedback sobre minha conclusão ou minha abordagem está errad

Estou usando esta implementação de um ObservableDictionary ObservableDictionary) porque preciso de consultas de desempenho usando a chav

Neste dicionário, coloco a coleção de objetos Model.

Na minha VM, declaro uma instância (Books) do dicionário e no XAML se liga a el

    <tk:DataGrid AutoGenerateColumns="False" Grid.Row="1" ItemsSource="{Binding Mode=TwoWay, Path=Books.Store}" Grid.ColumnSpan="2" Margin="3">
        <tk:DataGrid.Columns>
            <tk:DataGridTextColumn Binding="{Binding Mode=TwoWay, Path=Value.Name}" MinWidth="100" Header="Name" />
            <tk:DataGridTextColumn Binding="{Binding Mode=TwoWay, Path=Value.Details}" MinWidth="300" Header="Details" />
        </tk:DataGrid.Columns>        
    </tk:DataGrid>  

Se eu implementar INotifyPropertyChanged na VM for Books e alterar o valor de um nome de livro no código, a interface do usuário não será atualizad

Se eu implementar INotifyPropertyChanged na VM for Store e alterar o valor de um nome de livro no código, a interface do usuário não será atualizad

Se eu implementar INotifyProperyChanged no modelo e alterar o valor de um nome de livro no código, a interface do usuário será atualizad

O evento Alterado não é acionado no primeiro caso, porque o configurador de Dicionário não é chamado, é o Item (um Livro

Estou faltando alguma coisa porque, se esta é a interpretação correta, se eu quero notificações consistentes para meus modelos, independentemente de estarem vinculadas diretamente a XAML ou através de algum tipo de coleção, eu sempre gostaria que o modelo implementasse INotifyProperyChange

Aliás, além da referência da DLL, eu pessoalmente não vejo INotifyPropertyChanged como uma função de interface do usuário - acho que deve ser definida em um espaço de nome .net mais geral - meus 2 centavo

EDIT COMEÇA AQUI:

Estávamos em um debate semântico tão bom que perdi o cerne da minha pergunta, então aqui ela é postada novamente, mas com um exemplo muito simples de MVVM ilustra minha pergunt

Os modelos:

public class Book
{
    public string Title { get; set; )
    public List<Author> Authors { get; set; }
}

public class Author
{
    public string Name { get; set; }
}

O Provedor de Dados para gerar alguns dados fictícios

public class BookProvider
{
    public ObservableCollection<Book> GetBooks() {
        ObservableCollection<Book> books = new ObservableCollection<Book>();

        books.Add(new Book {
            Title = "Book1",
            Authors = new List<Author> { new Author { Name = "Joe" }, new Author { Name = "Phil" } }
        });

        books.Add(new Book {
            Title = "Book2",
            Authors = new List<Author> { new Author { Name = "Jane" }, new Author { Name = "Bob" } }
        });

        return books;
    }
}

The ViewModel

    public class BookViewModel : INotifyPropertyChanged
{
    private ObservableCollection<Book> books;
    public ObservableCollection<Book> Books {
        get { return books; }
        set {
            if (value != books) {
                books = value;
                NotifyPropertyChanged("Books");
            }
        }
    }

    private BookProvider provider;

    public BookViewModel() {
        provider = new BookProvider();
        Books = provider.GetBooks();
    }

    // For testing the example
    public void MakeChange() {
        Books[0].Title = "Changed";
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(String info) {
        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

ódigo @XAML atrás de Normalmente não faria isso dessa maneira - apenas por exemplo simples

public partial class MainWindow : Window
{
    private BookViewModel vm;

    public MainWindow() {
        InitializeComponent();

        vm = new BookViewModel();
        this.DataContext = vm;
    }

    private void Button_Click(object sender, RoutedEventArgs e) {
        vm.MakeChange();
    }
}

The XAML

<Window x:Class="BookTest.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="242*" />
        <RowDefinition Height="69*" />
    </Grid.RowDefinitions>
    <ListBox ItemsSource="{Binding Books}">
        <ListBox.ItemTemplate>
            <DataTemplate>
                <StackPanel Orientation="Vertical">
                    <TextBlock Text="{Binding Title}" />
                    <ListBox ItemsSource="{Binding Authors}">
                        <ListBox.ItemTemplate>
                            <DataTemplate>
                                <TextBlock Text="{Binding Name}" FontStyle="Italic" />
                            </DataTemplate>
                        </ListBox.ItemTemplate>
                    </ListBox>
                </StackPanel>
            </DataTemplate>
        </ListBox.ItemTemplate>
    </ListBox>
    <Button Grid.Row="1" Content="Change" Click="Button_Click" />
</Grid>

Conforme codificado acima, quando clico no botão e altero o valor no primeiro livro, a interface do usuário não mud

No entanto, quando movo o INotifyPropertyChanged para o Model, ele funciona bem (atualizações da interface do usuário) porque a alteração está no setter de propriedades do Model, e não Books na VM:

public class Book : INotifyPropertyChanged
{
    private string title;
    public string Title {
        get { return title; }
        set {
            if (value != title) {
                title = value;
                NotifyPropertyChanged("Title");
            }
        }
    }

    public List<Author> Authors { get; set; }

    public event PropertyChangedEventHandler PropertyChanged;

    protected void NotifyPropertyChanged(String info) {
        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

Volte à minha pergunta original, como faço para implementar isso sem implementar INotifyPropertyChanged no model

Obrigado

questionAnswers(3)

yourAnswerToTheQuestion