И если я хочу при вызове события ZoomChanged обрабатывать его в ViewModel , как мне это сделать?
И еще один вопрос. Также есть допустим TextBox и у него есть разные событие такие как: Tapped, DoubleTapped, PointerEnter, как же мне их обрабатывать в ViewModel когда они вызываются?
Не нужно так делать. События View должны обрабатываться внутри View (например - триггеры в xaml или же подписка на события контрола внутри окна), а не внутри ViewModel. Хоть и ViewModel является связующим звеном между доменной логикой и представлением, но оно ничего не должно знать об окне где его используют. Все, что находится в окне - делается внутри окна и нигде больше. События, цвета, шрифты и то что вы видите человеческим глазом - всё это часть представления которое меняется по щелчку пальцев и будет изменяться по ходу приложения еще 100500 раз. Чтобы избежать сильной связанности между представлением и логикой разделяют ответственности и в итоге окно отвечает само за себя.
Как же правильно? Да очень просто:
Сделаем обработчик события (его можно задать как в xaml так и внутри конструктора например, просто обратиться к событию myTextbox.DoubleTapped += OnDoubleTapped, и тогда не нужно будет привязывать через xaml, тут как удобно)
public class MyMainWindow : Window
{
private void OnDoubleTapped(object sender, DoubleTappedRoutedEventArgs e)
{
(sender as TextBox).Text = Guid.NewGuid().ToString();
}
}
Теперь можно сделать ViewModel. Для начала реализует INPC и сделаем метод SetProperty чтобы было легче писать код и вызывать событие. Так же добавлю свойство VMText которое привяжем в xaml (назвал так для отличия свойства контрола и свойства вьюмодели)
public class MyMainViewModel : INotifyPropertyChanged
{
private string _text;
public string VMText { get => _text; set => SetProperty(ref _text, value); }
public event PropertyChangedEventHandler? PropertyChanged;
protected void OnPropertyChanged([CallerMemberName] string prop = "")
{
PropertyChanged?.Invoke(this. new(prop));
}
protected bool SetProperty<T>(ref T field, T value, [CallerMemberName] string prop = "")
{
if(field == value)
return false;
field = value;
OnPropertyChanged(prop);
return true;
}
}
Можно перейти к xaml окна:
<TextBox Text={Binding VMText} DoubleTapped="OnDoubleTapped"/>
Теперь при вызове события DoubleTapped будет задаваться новый Guid и так же обновляться свойство во ViewModel которым вы можете пользоваться.
Сегодня Вы делаете проект на WPF, а завтра злой директор сказал: надо на ASP.NET Core да еще и чтоб слайдер картинок был, а у вас вся ViewModel захардкожена под WPF и слайдер реализован не внутри окна, а внутри ViewModel. Представляете сколько вы потратите времени просто на то чтобы переписать и захардкодить свою ViewModel под другой тип проекта снова? Вот и я не представляю. Думайте о масштабировании
<Button Click="обработчик">, а<Button Command = "{Binding ClickCommand}">). Сами события в XAML могут читать триггеры, вот решение выше это и есть триггеры + команды на события. – EvgeniyZ Jul 22 '22 at 09:54что б получить object- тут поищите реализации поудачней команд, их в интернете полно. К примеру я часто использую такую реализацию, как в этом ответе, она имеет не весь функционал, но если нужны чисто клики, то почему бы и нет, сразу в нужный тип конвертирует, вам лишь указать его какcommand = new RelayCommand<тип>(метод);и создать метод сразу с нужным типомprivate метод (тип value){ ... }. Более полные команды также легко найти. А тоobjectэто прям брр) – EvgeniyZ Jul 22 '22 at 10:20