views:

44

answers:

3

I have an MVVM application I am developing that is to the point where I'm ready to start putting together a user interface (my client code is largely functional)

I'm now running into the issue that I'm trying to get my application data to where I need it so that it can be consumed by the view model and then bound to the view.

Unfortunately, it seems that I've either got a few structural oversights, or I'm just going to have to face the reality that I need to be propogating events and raising excessive amounts of errors to notify view models that thier properties have changed.

Let me go into some examples of my issue:

I have a class "Unit" contained in a class "Test", contained in a class "Session" contained in a class "TestManager" which is contained in "TestDataModel" which is utilized by "TestViewModel" which is databound to by my "TestView" .... WHOA.

Now, consider that Unit (the bottom of the heiarchy) has a property called "Results" that is updated periodically, I want to expose that to my viewmodel and then databind it to my view, trouble is, the only way I can really think to do this is to perpetuate events WAY up a chain that say "I've been updated!" and then request the new value... This seems like an aweful way to do this. Alternatively, I could register a static event and raise it, and have the appropriate "Unit view model" grab the event and request the update. This SEEMS better... but... static events? Is that a taboo idea?

Also, having an expression like:

TestDataModel.TestManager.Session.Test.Unit.Results[i] Seems REALLY gross to have on a View Model.  

I know this all reeks of a bad design issue, but I can't figure out what I did wrong? Should I be using more singleton/container controlled lifetimes type objects? Register object instances with static helper containers? Maybe a Multiton? Obviously these are hard questions to answer without being intimate with the existing structure, but if you've run into situations like this, what did you do to refactor? Should I just live with this, add mass events, and propogate them?

A: 

If your view models support notification (e.g. via INotifyPropertyChanged) then regular databinding in your view will mean that the view updates itself. Maybe I'm missing something in the question?

Update

If you are concerned with the chain of properties, then you could have a ResultsViewModel which exposes Results, and then bind your view to Results. Results should be an observable collection and each Result should implement INotifyPropertyChanged. I am presuming your view displays a list of results.

chibacity
@chibacity, you are... I need to get data to the view model so that I can expose it to data binding, in some cases that means a LOT of property nesting.
Firoso
@firoso I see, it was just the way you were described propagating events up your viewmodel hierarchy and then requesting the updated value. This sounds like you are describing a manual process, rather than automatic databinding.
chibacity
@chibacity, I am! But at the top level, i'm using databinding, until I can get the data to a layer that should be exposed via databinding, i'm using event propagation tho.
Firoso
+4  A: 

The problem is that your TestView tries to know everything about your model. In reality you want to have simple views and use composition to assemble them to more complex ones. This way you'd have a view that simply deals with Units and nothing else (other views would deal with other aspects of your big model) This way your viewmodels would be accessing model through a well-defined API (e.g. to get Units, etc.) and there won't be a need to violate an encapsulation of your model by exposing its all internals for anyone to see.

PL
I was starting to realize this as I wrote this, but you just made it click. Thank you sir.
Firoso
A: 

You need UI events (not necessarily INotifyPropertyChanged) to signify when the Results have been updated. Prism includes an event aggregator if you want to use it, or you may be able to get by using custom C# events on your model object.

I don't recommend implementing INotifyPropertyChanged itself on your model object; use something more specific, e.g.

public event Action ResultsChanged

Once you have an event system of some kind set up, then on your ViewModel, hook into the Model event and fire the PropertyChanged event every time the Results change. Don't hesitate to create more ViewModel classes (one ViewModel per Result) if they're needed to make the databinding code work.

Peter Seale
This is kinda what I was running into as a problem, so it seems what i need is just more granularity and mapping of a VM heiarchy to map to my application heiarchy
Firoso