WPF MVVM: How to update Usercontrol data [closed]

大城市里の小女人 提交于 2019-12-02 16:13:24

问题


Starting with WPF and I like the MVVM pattern where I have a ViewModel locator as I'm quite used to IoC usage. However most blogs/articles say that a Usercontrol should not have a ViewModel. Which makes sense, but then I can't quite get how to update its data.

For example, suppose I have a Usercontrol (UC) that displayes a graph with data from a hardware device. I have the "IProvideGraphData" interface implemented and ready. But how to inject this into my Usercontrol?

I'd prefer this to be in the Usercontrol constructor but since the View doesn't call for the Usercontrol using IoC (via the ViewModel locator), I cant grasp how this should be done in a clean precise manner...

Thoughts?


回答1:


Not sure which blogs and articles you are reading, but UserControls absolutely can and do have their own ViewModels (VM). Do they always? No! Do they ever? Absolutely! It all depends on the purpose of the User Control.

If you are breaking up your Main View into Master and Child Views(i.e. Window contains UserControls) as to have a well defined hierarchy, the ViewModels should follow the same hierarchy as well. Meaning, your main Window has the Master VM for its DataContext, where the Master VM exposes the Child VMs as Properties, and Child Views (i.e. UCs) use those Child VM Properties for their DataContext.

Here the inherited ViewModelBase implements the INotifyPropertyChanged interface. The Master VM will look something like this:

public class MasterViewModel : ViewModelBase
{
    public MasterViewModel()
    {
        ChildVM = new ChildVMType();
    }

    private ChildVMType childVM;
    public ChildVMType ChildVM
    {
        get { return childVM; }
        set { SetProperty(ref childVM, value); }
    }
    ...
}

The Master View/ViewModel will use the View-First Construction principal, where you instantiate the master VM declaritively in the XAML (or whatever other way you prefer.). The point is, the View instantiates the ViewModel.

<Window.DataContext>
    <local:MainViewModel/>
</Window.DataContext>

Child VMs, on the other hand, are instantiated by the Master ViewModel (see VM above), usually in the constructor, following the ViewModel-First Construction Principal.

To inject the child VM into the user control, you can do something like this somewhere in your Master View (i.e. Main Window):

<ContentControl>
    <local:MyChildUCview DataContext="{Binding ChildVM}"/>
</ContentControl> 

where ChildVM is a property exposed on the Master ViewModel (see above).

There are many other ways you can wire this up, but the idea is the same.

What you should aim to achieve is that the Child VM takes care of all the logic that the master VM is not concerned with. This will allow for a much greater separation of concerns and will vastly improve maintainabilty and extensibility.

To allow for a 2-way communciation between the Master and Child VMs, you would use Events. For example, your Child VM has an event that your Master VM subscribes to. When something happens in the Child VM that the Master needs to know about, the Child raises the event and passes the needed arguments to the Master. The master can of course speak directly to the Child as it is its own property.

If you are serious about learning this well, I would strongly recommend that you watch a course on Pluralsight, namely "WPF MVVM in Depth" by Brian Noyes. You can sign up for a free trial, which should be enough to get through this course.



来源:https://stackoverflow.com/questions/49843610/wpf-mvvm-how-to-update-usercontrol-data

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