WPF MVVM:如何更新Usercontrol数据 [英] WPF MVVM: How to update Usercontrol data

查看:474
本文介绍了WPF MVVM:如何更新Usercontrol数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

从WPF开始,我喜欢MVVM模式,这里有一个ViewModel定位器,因为我已经习惯了IoC的使用.但是,大多数博客/文章都说用户控件不应具有ViewModel.这是有道理的,但后来我还不太了解如何更新其数据.

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.

例如,假设我有一个用户控件(UC),该控件显示带有来自硬件设备的数据的图形.我已经实现并准备好了"IProvideGraphData"接口.但是如何将其注入到我的Usercontrol中?

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?

我希望它位于Usercontrol构造函数中,但是由于View不需要使用IoC(通过ViewModel定位器)来调用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...

有想法吗?

推荐答案

不确定您正在阅读哪些博客和文章,但UserControls绝对可以并且确实拥有自己的ViewModel(VM).他们总是吗?不!他们曾经吗?绝对地!这完全取决于用户控件的目的.

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.

如果要将主视图分为主视图和子视图(即,窗口包含UserControls)以具有定义良好的层次结构,则ViewModel也应遵循相同的层次结构.意思是,您的主窗口具有用于其DataContext的主VM,其中主VM将子VM公开为属性,而子视图(即UC)将那些子VM属性用于其DataContext.

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.

此处继承的ViewModelBase实现INotifyPropertyChanged接口.主虚拟机将如下所示:

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); }
    }
    ...
}

Master View/ViewModel将使用View-First Construction主体,在该主体中,您可以在XAML中(或您喜欢的任何其他方式)以声明方式实例化Master VM.关键是,View实例化了ViewModel.

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>

另一方面,子VM由主ViewModel(请参见上面的VM)实例化,通常在构造函数中遵循ViewModel-First构造主体.

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.

要将子VM注入到用户控件中,您可以在主视图(即主窗口)的某处执行以下操作:

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> 

其中ChildVM是在主ViewModel上公开的属性(请参见上文).

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.

您应该实现的目标是,子VM负责处理主VM所不关心的所有逻辑.这样可以更大程度地分离关注点,并大大提高可维护性和可扩展性.

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.

如果您想认真学习这个技巧,我强烈建议您观看有关Pluralsight的课程,即布莱恩·诺耶斯(Brian Noyes)的"WPF深度MVVM" .您可以注册一个免费试用版,这应该足以完成本课程.

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.

这篇关于WPF MVVM:如何更新Usercontrol数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆