using multiple data sources on single view

Mar 7, 2011 at 7:38 PM


I have a view which contains a tab strip (2 tabs).  These 2 tabs each show a treeview which the users will use to display item details in another UI section (Same details, just a different way to navigate there).  I created the object graph for each list and included the XAML on the UI.  So far so good except the second list will not load.  My question is: How do I join these two viewmodels so they will both be loaded when I load the view without creating a new root object?  I am asking this because the viewmodel implement a ViewModel of type (one of my object -- usually the root of my object graph) which implies I should create another BO just to contain the 2 root lists. Is this the case?

I am asking because I beleive this is a UI specific requirement because the navigation can be tested with both lists separately.  Any input would be appreciated. 

Thank you.

Mar 7, 2011 at 8:38 PM

If I understand correctly, you are looking at this as one view (the tab strip), with two parts (each tab). But it is one logical view.

And if I understand correctly, each tab binds to a different viewmodel - presumably because the shape of the data required by each tab is different.

So one view, two viewmodels. That does mean you need a parent viewmodel to contain the two child viewmodel objects, because Bxf is designed around a "one view, one viewmodel" concept.

This shouldn't decrease testability. Each child viewmodel can be created and tested individually, and the parent viewmodel is probably nothing more than a class with two properties - one property for each child viewmodel.

Mar 8, 2011 at 1:21 PM

That is exactly what I meant. 

I ended up creating a simple class with two properties  as you suggested but I still can't seem to get around the fact that bxf requires the viewmodel to implement ViewModel<T> (Well as far as I understand it anyways). 

This is where I am stuck.   What I currently obtain is an error saying "Unsupported type of source for a collection view."  That is why I was thinking I would need to create a root BO for this particular case. 

Thanks for the quick reply. 

Mar 8, 2011 at 4:06 PM

If you look at the ShowView method, you'll see that the viewmodel parameter type is object. In other words, Bxf doesn't really care at all what type you use for a viewmodel.

Typically a viewmodel will implement one or more properties, so it must implement INotifyPropertyChanged.

And typically a viewmodel will implement one or more verbs (methods), and they must conform to the method signatures required by your UI event router or commanding model (such as TriggerAction, the Blend event trigger/behavior model, XAML commanding, etc).

I often subclass DependencyObject to get INotifyPropertyChanged "for free", but that's not a requirement.

And if my model objects are based on CSLA I'll often use ViewModel<T> - but that's a CSLA thing, not a Bxf thing.

Nov 15, 2011 at 1:21 PM

I'm having a hard time to figure it out how to assign my ViewModel to my View. I'm having the same scenario: "1 View, 2 ViewModels" depending on the type of the user that has logged in into my sistem. I have 2 types of users therefore 2 ViewModels for every type. I created 1 parent ViewModel with 2 properties for each child ViewModel, but I don't know how to tell my View to which property to bind to. My child ViewModels are exactly the same with the difference that the first inherits ViewModel<User1> and the second inherits ViewModel<User2>. User1 and User2 are both classes implemented with csla. They have very common properties and some different ones, but in my View I use only their common properties to bind my controls to.

Nov 15, 2011 at 2:01 PM
You could just check the rule and launch the viewmodel that you want:
                    if (Csla.ApplicationContext.User.IsInRole("APPROVAL_VIEW") || Csla.ApplicationContext.User.IsInRole("APPROVAL_EDIT") || Csla.ApplicationContext.User.IsInRole("APPROVAL_ADD"))
                            typeof (ApprovalRootView).AssemblyQualifiedName,
                            "rootViewModelViewSource", new ViewModels.ApprovalRootViewModel(),
                    else if (Csla.ApplicationContext.User.IsInRole("ISSUE_VIEW") || Csla.ApplicationContext.User.IsInRole("ISSUE_EDIT") || Csla.ApplicationContext.User.IsInRole("ISSUE_ADD")) 
                            typeof (DashboardRootView).AssemblyQualifiedName,
                            "rootViewModelViewSource", new ViewModels.DashboardRootViewModel(),
                        StatusText.Text = "Access Denied. Please See Your Manager.";

Nov 16, 2011 at 9:25 AM

Thank you!