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

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

问题描述

我的通用问题是标题状态,最好在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?

我猜测答案是通过一些加载的事件处理在施工之后,但我想知道如何在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。 ViewModels绑定到每个View的根控制DataContext通过ViewModelLocator的想法,Laurent Bugnion已经投入到MVVM Light中。这允许通过静态资源查找ViewModels,并通过依赖注入框架(在本例中为Unity)来控制ViewModels的生命周期。它还允许Expression Blend查看关于ViewModel的所有内容以及如何绑定它们。

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中发现的Messaging系统完成此任务。当您在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属性的设置者是在其构造函数中广播更新的消息的另一个感兴趣的ViewModels注册表。看来,我目前正在建设时通过ViewModel设置SelectedItem,它不允许构建和注册sub-ViewModels。

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的方法来知道什么时候有Loaded,然后可以继续加载数据并完成安装阶段。

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

}

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

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