чтоб его создать нужен класс. Класс называют как View но с припиской VM или ViewModel это делается потому что так легко найти нужный файл

public partial class MainWindowVM : ObservableObject
{
}

он должен у наследоваться от ObservableObject или ObservableValidator

ObservableValidator нужен когда нужна валидация свойств он добавляет свойства и метод

и также класс должен быть частичным partial так как библиотека генерирует свой код для работы его можно увидеть если нажать CTRL + ЛКМ по имени типа класс покажется окно Pasted image 20260607110158 так можно посмотреть что было сгенерировано

Атрибуты

у библиотеки есть несколько атрибутов для реализации VM

ObservableProperty

public partial class MainWindowVM : ObservableObject
{
    [ObservableProperty]
    private string _name;
    [ObservableProperty]
    private int _age;
}

это делается чтоб пометить поле для генератора которое уже сгенерирует полное свойство

генерирует он такое он такое

 public string Name
 {
     get => _name;
     [global::System.Diagnostics.CodeAnalysis.MemberNotNull("_name")]
     set
     {
         if (!global::System.Collections.Generic.EqualityComparer<string>.Default.Equals(_name, value))
         {
             OnNameChanging(value);
             OnNameChanging(default, value);
             OnPropertyChanging(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangingArgs.Name);
             _name = value;
             OnNameChanged(value);
             OnNameChanged(default, value);
             OnPropertyChanged(global::CommunityToolkit.Mvvm.ComponentModel.__Internals.__KnownINotifyPropertyChangedArgs.Name);
         }
     }
 }

как можно увидеть в мести со свойством он генерирует частичные методы

  • OnNameChanging(value) вызывается до присвоение нового значения свойства что позволяет отменить изменение
  • OnNameChanging(oldValue,newValue) вызывается до присвоение нового значения свойства что позволяет отменить изменение но в отличие предаёт старое значение
  • OnNameChanged(value) этот метод вызывается уже после присвоения передовая новое значение
  • OnNameChanged(oldValue,newValue) этот метод вызывается уже после присвоения передовая новое значение но также передовая старое

Каждое поле с атрибутом [ObservableProperty] создаёт для каждого свойство и по 4 частичных методов

Что интересно Changing чтоб отменить изменение нужно выбросить исключение Пример:

partial void OnUserNameChanging(string oldValue, string newValue)
{
    if (string.IsNullOrWhiteSpace(newValue))
    {
        // Можно выбросить исключение или установить флаг ошибки
        throw new ArgumentException("Имя не может быть пустым");
    }
    
    if (newValue.Length > 20)
    {
        // Но можно выбросить исключение, чтобы SetProperty не выполнился
        throw new ArgumentException("Максимум 20 символов");
    }
}

RelayCommand

Этот атрибут нужен чтоб объявить команду для вызова метода

[RelayCommand]
private void Method()
{
	
}
[RelayCommand]
private async Task Method2Async()
{
	
}

Модификатор доступа тут не важен

тут генерируется публичный объект ICommand который привязывается к свойствам у элементов

что интересно: имя ICommand будет таким MethodCommamd берётся имя метода и добавляется слово Commamd и если у метода есть приставка Async то она стерпится и получится было Method2Async стало Method2Command тут надо аккуратней две одиновыми именами.

Важно: методы не должны возвращать не тачего надо использовать либо void или Task для асинхронного кода ток Task должен быть без дженерика например Task<int> так нельзя. Также у таких методов может быть максимум ток один параметр а иначе команда не сгенерируется.


Подключение

чтоб VM заработало нужно его присвоить

public MainWindow(MainWindowVM vm)
{
    InitializeComponent();
    DataContext = vm;   
}

тут важен экземпляр класса как он будет получен зависит от вас

Важно: Присвоение должно быть после вызова InitializeComponent();


Привязка (Binding)

 <TextBox Text="{Binding Name}"/>
 <Button Command="{Binding Method2Command}" Content="Моя команда"/>

Привязка осуществляется через слово "{Binding свойство}" при привязки нужно чтоб свойства были нужными типами

например для свойства Text у TextBox это string или любой числовой тип а у элементов которые просто текст выводят Text принимает object то есть любой тип и вызовет ToString у него а для свойства Command должен быть ICommand В случаи не правильного со постановления типа будет ошибка компиляции что расскажет что не так

Большинства свойств умеют делать привязку а если не умеют нужно вручную менять свойства у VM через событие

И если типы разные у свойства VM и свойства элемента и вы хотите привязать его привязать то требуется конвертор

Built with LogoFlowershow