Модель описывает данные. Представление определяет внешний вид экрана. Вьюмодель - это модель, которая предназначена для использования данных из модели внутри представления, причём во вьюмодели можно добавлять какие-то поля только для удобства представления. Одна вьюмодель вполне может использовать несколько разных моделей.
Первейший путь для показа данных в представлении - привязка (биндинг) данных, а также - специальные поля контрола (например, DisplayMemberPath).
Команды используются для обратной связи от пользователя в представлении во вьюмодель.
Свойства зависимости сами по себе обычно не используются напрямую, а просто добавляют возможностей для биндинга.
Расширения разметки дают связывать несколько классов в одном контроле.
В представлении вполне можно обойтись без вьюмодели, используя саму модель (передав её как датаконтекст). Но у модели обычно нет интерфейса INotifyPropertyChanged, и вьюмодель как раз реализует её для использования биндинга, а также добавляет команды и доп.свойства. Для одной модели вполне может быть несколько вьюмоделей, по одному для представлений, или наоборот, одна вьюмодель вполне может подходить для нескольких представлений.
В примере можно увидеть, что в представлении можно использовать как свойства вьюмодели, так и исходные данные модели.
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public string MiddleName { get; set; }
}
public class EditPersonVm : BaseViewModel // который реализует INotifyPropertyChanged
{
private readonly Person _person;
public Person Person => _person;
private string _firstName;
public string FirstName
{
get => _firstName;
set { _firstName = value; RaisePropertyChanged(); }
}
private string _lastName;
public string LastName
{
get => _lastName;
set { _lastName= value; RaisePropertyChanged(); }
}
private string _middleName;
public string MiddleName
{
get => _middleName;
set { _middleName= value; RaisePropertyChanged(); }
}
public string InitFullName => $"{_person.LastName} {_person.FirstName[0]}. {_person.MiddleName[0]}.";
public RelayCommand OkButton { get; set; } = new RelayCommand(Save);
public EditPersonVm(Person person)
{
_person = person;
FirstName = person.FirstName;
LastName = person.LastName;
MiddleName = person.MiddleName;
}
private void Save()
{
//
}
}
<Window ...>
<StackPanel Orientation="Vertical">
<Label Content="Изначальное имя:"/>
<StackPanel>
<TextBlock Text="{Binding Person.LastName}"/>
<TextBlock> </TextBlock>
<TextBlock Text="{Binding Person.FirstName}"/>
<TextBlock> </TextBlock>
<TextBlock Text="{Binding Person.MiddleName}"/>
</StackPanel>
<Label Content="Фамилия:"/>
<TextBox Text="{Binding LastName, UpdateSourceTrigger=PropertyChanged}"/>
<Label Caption="Имя:"/>
<TextBox Text="{Binding FirstName, UpdateSourceTrigger=PropertyChanged}"/>
<Label Caption="Отчество:"/>
<TextBox Text="{Binding MiddleName, UpdateSourceTrigger=PropertyChanged}"/>
<Button Content="OK" Command="{Binding OkCommand}">
</StackPanel>
</Window>