Is it OK to subscribe to the ViewModel's .NET events from the View in MVVM?

可紊 提交于 2020-01-05 23:18:20

问题


I am writing this major memory trainer using the MVVM pattern by animating labels containing 2 digit numbers across the screen and asking the user to quickly type in the corresponding mnemonic for each number. It is entirely up to the View how the animation is done so there will be some code behind for this. When the correct mnemonic is typed into the UI or when the number disappears off the screen Commands will be executed from the View to relay that this has happened.

In the ViewModel I want to periodically fire off new numbers with which the View animates (as it pleases).

What's the best way of achieving this? I can have an ObservableCollection<> in the ViewModel but I want to do more than simply bind to it, I will need to execute a method in the code behind when numbers are added and removed.

Is it in accordance with MVVM to use simple .NET events in the ViewModel and subscribe to them with: DataContext.NumberAdded += new NumberAddedEventHandler(....) or is there another way I should be doing it?


回答1:


A View is meant to be a user-friendly reflection of the ViewModel. If you have view-specific logic to run (such as triggering an animation), there's no reason not to use code-behind to run it.

Providing you keep your UI and data layers separate, you're fine.

That said, providing a NumberAdded event from the ViewModel doesn't really make sense to me if you're only using it from the View layer. That's mixing up your layers.

Instead I would simply use the regular CollectionChanged

((MyViewModel)this.DataContext).Numbers.CollectionChanged += 
    new CollectionChangedEventHandler(....);

Depending on how your collection is bound to the UI, you may also be able to use a UI event, or possibly triggers instead.

I thought elements with an ItemsSource raised an event when an item got added or removed, or you could simply cast the ItemsSource property into a collection and hook up to the CollectionChanged event there without needing to reference MyViewModel

void SomeItemsControl_DataContextChanged(...)
{
    var collection = (SomeItemsControl.ItemsSource as ObservableCollection);
    if (collection != null)
        collection.CollectionChanged += new CollectionChangedEventHandler(....);
}



回答2:


Why do you reckon binding to it is bad?

I would probably bind to the ObservableCollection<T> from the View.

Create a DependencyProperty of ObservableCollection<T> in the View and on the PropertyChanged Callback subscribe to the OnCollectionChanged event which can then process the animation accordingly based on the contents of the ObservableCollection<T> in the View.

This way the VM just updates the collection with these numbers that you mention and the View is hooked up to action whenever the collection changes in the manner it desires fit




回答3:


Use Attached Behaviours to bind your viewmodel properties to any custom behaviour you need.



来源:https://stackoverflow.com/questions/16299955/is-it-ok-to-subscribe-to-the-viewmodels-net-events-from-the-view-in-mvvm

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!