example for NVL with MVVM

example for NVL with MVVM

Old forum URL: forums.lhotka.net/forums/t/10816.aspx


TSF posted on Wednesday, October 26, 2011

I'm trying to learn MVVM, and I've been looking at some of the e-book example projects.  The CslaMvvmSl solution shows some scenarios, but I'm not sure what to do in the case of exposing a NVL object in my view model.  This example project shows this view model (below), but the editor barks at me trying to use the Model.OrderBy line for a NVL object.  Can someone point me in the right direction, or let me know of other sample MVVM projects that use NVL objects?  Thanks.

public ObservableCollection<PersonItemViewModel> PersonList
{
   get
   {
        var result = new ObservableCollection<PersonItemViewModel>();
        if (Model != null)
        {
             foreach (var item in Model.OrderBy(c => c.Id))
             {
                   result.Add(new PersonItemViewModel(item));
             }
         }
         return result;
    }

StefanCop replied on Wednesday, October 26, 2011

Did you declare

using System.Linq;  ?

RockfordLhotka replied on Wednesday, October 26, 2011

The current ProjectTracker code (in svn) uses a NVL in the ProjectEdit and ResourceEdit views/viewmodels.

In reality though, I find that fewer and fewer NVL types are being used in XAML, because people want more than simple text in the combobox dropdown. So the more common case is to return a read-only list with richer data so the combbox can include text+images or something like that.

Rarely do you need to wrap the combobox items in child viewmodels. You'd only do that if you were adding buttons or hyperlinks to the content in the dropdown itself - and I'm not even sure that would work (?)

I just expose the NVL or read-only list directly as a property off my viewmodel so the view can bind to the list.

TSF replied on Thursday, October 27, 2011

Rocky, I think I understand what you're saying (about exposing the NVL as a property off the main VM), but being new to MVVM I'm not sure how I would go about that.  I'm having a hard time thinking about what it should look like.  If I have a ReadOnlyListBase class called AgentInfoList, and it is exposed via the following VM (which is the main VM for the user control):

public class AgentViewModel : ViewModel<AgentInfoList> {}

...then do I just do the following in this VM to expose the NVL object?

public MyNVL MyList
{
     get { return new MyNVL(); }
}

I guess that thing that is confusing me is that I've been assuming that a VM exposes one and only one CSLA class, and if your window needs to display multiple sets of data then you have multiple VMs for that one window, with a separate VM for every object exposed.  Is my understanding incorrect?  Thanks.

RockfordLhotka replied on Thursday, October 27, 2011

A viewmodel is coupled to the view, and its job is to expose the properties and command/verb/methods required by the view.

So if the view uses an editable object, and a NVL, then the viewmodel should expose both objects for the view to use.

Additionally:

If the view has "sub-views" or "sub-regions", each of those might have a viewmodel. The parent viewmodel should expose those child viewmodels as properties.

Just like the view contains the sub-view, the parent viewmodel contains the child viewmodel.

 

In short, the viewmodel structure mirrors the view and sub-views, not the business object model.

TSF replied on Thursday, October 27, 2011

So if you want a ViewModel to expose two or more objects, which one do you put in the class definition?  According to the example below, <T> in ViewModel<T> is AgentInfoList.  But what if I need two other models exposed in this same view?  How do I determine which model is referenced as T?

 

 

 

public class AgentViewModel : ViewModel<AgentInfoList>

Sorry - some of uncertainty is also probably related to my newness to CSLA in general.  Thanks for your help.

RockfordLhotka replied on Thursday, October 27, 2011

The ViewModelBase class in Csla.Xaml is designed to manage a business object. It is only useful if you are using it to manage a business object, and you shouldn't bother with it for objects you don't need to manage.

There's nothing to manage with a NVL, so ViewModelBase offers little or no value.

There's absolutely something to manage with any editable object, especially an editable root object, and I almost always use a subclass of ViewModelBase to manage my editable objects.

If my root viewmodel derives from ViewModelBase, I'll make T be the type of the editable object, and I'll expose the NVL as a property.

But in reality, I tend to use the async data portal for WPF/SL/WP7 - in which case T is a unit of work object, and I'll expose two properties from the root viewmodel:

  1. A ViewModelBase subclass where T is the editable business object
  2. The NVL collection

The WPF/SL ebook and ProjectTracker sample demonstrates this exact thing.

The root viewmodel for the ProjectEdit view is ProjectGetter (managing a ProjectGetter unit of work object).

It exposes a ProjectEditViewModel property, and the ProjectEdit viewmodel manages a ProjectEdit editable root business object.

It also exposes a RoleList property, directly returning the RoleList NVL business object.

Copyright (c) Marimer LLC