MVVM在ViewModel构建期间或之后加载数据? [英] MVVM load data during or after ViewModel construction?

查看:180
本文介绍了MVVM在ViewModel构建期间或之后加载数据?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的一般问题是作为标题陈述,最好在ViewModel构建过程中或之后通过一些Loaded事件处理加载数据?

My generic question is as the title states, is it best to load data during ViewModel construction or afterward through some Loaded event handling?

我猜的答案是通过一些Loaded事件处理后的建设,但我想知道如何是最干净地协调ViewModel和View之间?

I'm guessing the answer is after construction via some Loaded event handling, but I'm wondering how that is most cleanly coordinated between ViewModel and View?

这里有更多的细节我的情况和特定的问题我试图解决:

Here's more details about my situation and the particular problem I'm trying to solve:

我使用MVVM Light框架以及Unity for DI。我有一些嵌套视图,每个绑定到一个相应的ViewModel。 ViewModel通过ViewModelLocator的想法绑定到每个View的根控件DataContext,Laurent Bugnion已经把它放入MVVM Light。这允许通过静态资源查找ViewModel,并通过依赖注入框架(在这种情况下为Unity)控制ViewModel的生命周期。它还允许Expression Blend查看关于ViewModels的一切以及如何绑定它们。

I am using the MVVM Light framework as well as Unity for DI. I have some nested Views, each bound to a corresponding ViewModel. The ViewModels are bound to each View's root control DataContext via the ViewModelLocator idea that Laurent Bugnion has put into MVVM Light. This allows for finding ViewModels via a static resource and for controlling the lifetime of ViewModels via a Dependency Injection framework, in this case Unity. It also allows for Expression Blend to see everything in regard to ViewModels and how to bind them.

所以无论如何,我有一个父视图有ComboBox数据绑定在它的ViewModel中有一个ObservableCollection。 ComboBox的SelectedItem也被绑定(双向)到ViewModel上的一个属性。当ComboBox的选择更改时,这是在其他视图和子视图中触发更新。目前,我通过在MVVM Light中找到的消息系统来完成此任务。这是非常好的和预期当你选择不同的项目在ComboBox。

So anyway, I've got a parent View that has a ComboBox databound to an ObservableCollection in its ViewModel. The ComboBox's SelectedItem is also bound (two-way) to a property on the ViewModel. When the selection of the ComboBox changes, this is to trigger updates in other views and subviews. Currently I am accomplishing this via the Messaging system that is found in MVVM Light. This is all working great and as expected when you choose different items in the ComboBox.

然而,ViewModel在构建期间通过一系列初始化方法调用获取其数据。这似乎只是一个问题,如果我想控制什么是ComboBox的初始SelectedItem。使用MVVM Light的消息系统,我目前已经设置了ViewModel的SelectedItem属性的setter是广播更新的属性,而其他感兴趣的ViewModels在其构造函数中为消息注册。看来我正在尝试在构建时通过ViewModel设置SelectedItem,这不允许子ViewModel被构造和注册。

However, the ViewModel is getting its data during construction time via a series of initializing method calls. This seems to only be a problem if I want to control what the initial SelectedItem of the ComboBox is. Using MVVM Light's messaging system, I currently have it set up where the setter of the ViewModel's SelectedItem property is the one broadcasting the update and the other interested ViewModels register for the message in their constructors. It appears I am currently trying to set the SelectedItem via the ViewModel at construction time, which hasn't allowed sub-ViewModels to be constructed and register yet.

最清晰的方式来协调ViewModel中的SelectedItem的数据加载和初始设置?我真的想坚持放在View的代码隐藏在合理的。我想我只需要一个方法让ViewModel知道什么东西被加载,然后它可以继续加载数据并完成设置阶段。

What would be the cleanest way to coordinate the data load and initial setting of SelectedItem within the ViewModel? I really want to stick with putting as little in the View's code-behind as is reasonable. I think I just need a way for the ViewModel to know when stuff has Loaded and that it can then continue to load the data and finalize the setup phase.

提前感谢

推荐答案

对于事件,您应该使用MVVM Light Toolkit中的EventToCommand。使用这个,您可以将任何ui元素的任何事件绑定到relaycommand。请查看他在EventToCommand上的文章:

For events you should use the EventToCommand in MVVM Light Toolkit. Using this you can bind any event of any ui element to relaycommand. Check out his article on EventToCommand at

http://blog.galasoft.ch/archive/2009/11/05/mvvm-light-toolkit-v3-alpha-2- eventtocommand-behavior.aspx

下载示例并查看。这很棒。你不需要任何代码。示例如下:

Download the sample and have a look. Its great. You won't need any codebehind then. An example is as follows:

<Page x:Class="cubic.cats.Wpf.Views.SplashScreenView"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
      xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
      xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras"
      mc:Ignorable="d" 
      d:DesignHeight="300" d:DesignWidth="300"
    Title="SplashScreenPage">

    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <cmd:EventToCommand Command="{Binding LoadedCommand}" />
        </i:EventTrigger>        
    </i:Interaction.Triggers>

    <Grid>
        <Label Content="This is test page" />
    </Grid>
</Page>

,并且视图模式可能如下

and the view mode could be like this

 public class SplashScreenViewModel : ViewModelBase
    {
        public RelayCommand LoadedCommand
        {
            get;
            private set;
        }

        /// <summary>
        /// Initializes a new instance of the SplashScreenViewModel class.
        /// </summary>
        public SplashScreenViewModel()
        {
            LoadedCommand = new RelayCommand(() =>
            {
                string a = "put a break point here to see that it gets called after the view as been loaded";
            });
        }
    }

如果您希望视图模型具有EventArgs ,您可以将PassEventArgsToCommand简单设置为true:

if you would like the view model to have the EventArgs, you can simple set PassEventArgsToCommand to true:

<i:Interaction.Triggers>
            <i:EventTrigger EventName="Loaded">
                <cmd:EventToCommand PassEventArgsToCommand="True" Command="{Binding LoadedCommand}" />
  </i:EventTrigger>        
</i:Interaction.Triggers>

,视图模型将类似于

public class SplashScreenViewModel : ViewModelBase
{
    public RelayCommand<MouseEventArgs> LoadedCommand
    {
        get;
        private set;
    }

    /// <summary>
    /// Initializes a new instance of the SplashScreenViewModel class.
    /// </summary>
    public SplashScreenViewModel()
    {
        LoadedCommand = new RelayCommand<MouseEventArgs>(e =>
        {
            var a = e.WhateverParameters....;
        });
    }

}

这篇关于MVVM在ViewModel构建期间或之后加载数据?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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