mplementación @WPF MVVM INotifyPropertyChanged - Modelo o ViewModel

He leído una serie de debates sobre dónde implementar INotifyPropertyChanged aquí en StackOverflow y otros blogs, pero parece que hay casos en los que tiene que implementarlo en el Modelo. Este es mi escenario: estoy buscando comentarios sobre mi conclusión o mi enfoque es incorrecto.

Estoy usando esta implementación de un ObservableDictionary ObservableDictionary) porque necesito consultas efectivas utilizando la clave.

En este diccionario coloco la colección de objetos Modelo.

En mi VM, declaro una instancia (Libros) del diccionario y en el enlace XAML a ella.

    <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>  

Si implemento INotifyPropertyChanged en la VM para libros y cambio el valor del nombre de un libro en el código, la IU no se actualiza.

Si implemento INotifyPropertyChanged en la VM for Store y cambio el valor del nombre de un Libro en el código, la IU no se actualiza.

Si implemento INotifyProperyChanged en el Modelo y cambio el valor del nombre del Libro en el código, la IU se actualiza.

El evento modificado no se activa en el primer caso porque no se llama al configurador del diccionario, es su elemento (un libro).

Me falta algo porque si esta es la interpretación correcta, si quiero notificaciones consistentes para mis Modelos, independientemente de si están vinculados directamente desde XAML o mediante algún tipo de colección, siempre me gustaría que el Modelo implemente INotifyProperyChanged.

Btw, además de la referencia dll, personalmente no veo INotifyPropertyChanged como una función de interfaz de usuario; creo que debería definirse en un espacio de nombres .net más general: mis 2 centavos.

EDIT COMIENZA AQUÍ:

eníamos un debate semántico tan bueno que me perdí el núcleo de mi pregunta, así que aquí está publicado nuevamente, pero con un ejemplo muy simple de MVVM ilustra mi pregunta.

Los modelos

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

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

El proveedor de datos para generar algunos datos ficticios

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 detrás de Normalmente no lo haría de esta manera, solo por ejemplo simple

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>

Como se codificó anteriormente, cuando hago clic en el botón y cambio el valor en el primer Libro, la IU no cambia.

Sin embargo, cuando muevo INotifyPropertyChanged al Modelo, funciona bien (actualizaciones de la interfaz de usuario) porque el cambio está en el setter de propiedades del Modelo, no en los Libros en la 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));
        }
    }
}

Volviendo a mi pregunta original, ¿cómo puedo lograr esto sin implementar INotifyPropertyChanged en el Modelo?

Gracias

Respuestas a la pregunta(3)

Su respuesta a la pregunta