views:

378

answers:

2

As I knock off more and more MVVM-related issues with my current application, more just keep popping up. :)

The current implementation that I am trying to replace involves a StackPanel whose children are more or less dynamically generated (via looking in a configuration file). Each child is an instance of a UserControl. Before, what I did was assign a name to the StackPanel, and then in the Window_Loaded event handler, I'd simply determine the necessary number of children, instantiate one UserControl for each, and also assign the UserControl an ID so I'd know the proper source for the Buttons clicked on a particular UserControl instance; each UserControl has 3 buttons on it.

So I know I want to bind the StackPanel to a collection. This of course, is not possible, as I need to use something that derives from ItemsControl, like ListBox or ListView (or even ItemsControl itself). To keep it easy in the first iteration of MVVM-ifying, I'll just use a ListBox.

Now the question is, should my ObservableCollection in the code-behind be a ObservableCollection? I believe this means that no matter how I skin my GUI, this ListBox will always have children that look however they do in MyUserControl's XAML file. I'd like this to be customizable as well, but I assume this means I have to apply the MVVM pattern to the UserControl as well.

+3  A: 

If you want each of your list items to have different templates, and want to stick to an MVVM style, you're better off not thinking in terms of UserControls.

You can have your main view to have a ListBox bound to an observable collection of View Model instances. If you setup your data templates to map the ViewModel classes to their appropriate UserControl, you don't need to ever explicitly load UserControls - just bind any ItemsControl to your collection of ViewModels, and let the data templates take care of constructing and mapping this to the correct UserControl for that VM.

Reed Copsey
I don't need each ListItem to have a different template, but I definitely want to stick to an MVVM style. It turns out that I can't do what I had proposed anyway, since that UserControl already references the ViewModel, and therefore I'd end up with a circular reference.I'll give that ViewModel approach a shot and see where it takes me. Thanks!
Dave
Yeah - Each Item can be a separate ViewModel class, which means it will get its own template (if you have a DataTemplate setup for each ViewModel to map it to an appropriate View). This can be a separate UserControl. I do this all the time - it basically makes it a list of VMs, completely separate from the Views - pure MVVM :)
Reed Copsey
I got sidetracked just now trying to help someone in the Expression Blend forum, but I'm going to look into this method of "binding" a VM to a V using DataTemplates. It's not something I've done before, or even heard of. I just love trying to apply MVVM -- I find that I'm learning so much more about WPF through the process! Thank you for your suggestion!
Dave
Read Josh Smith's article - this is kind of the "original" MVVM approach - setup the ViewModel, and use a DataTemplate to pick the view...
Reed Copsey
If I'm understanding everything correctly, doesn't this mean that I don't even need that UserControl? Since it's essentially just three buttons with labels next to them, the DataTemplate itself could easily render it the way I want it to look. So the UserControl just becomes some plain old class... Right?
Dave
Yes! (15 charac
Aviad P.
works great! although now I have another question... time to make a new post once I do more searching here. marked as answer, thank you again!
Dave
+1  A: 

Your collection doesn't have to be an ObservableCollection if it doesn't have to. The "Observable" part of ObservableCollection is simply a matter of supplying events to notify others that the collection has changed, it is by no means related to visual representation.

ObservableCollection is very well suited for MVVM because of all the event notification it supplies, but ultimately, whether you use a List<T> or an ObservableCollection<T> makes no difference in the way things appear visually at any given point in time.

Aviad P.
Thanks for the clarification regarding ObservableCollections. I figured that I would just use it for databinding any sort of collection, but you've reminded me that it's mainly for change notification. In my app, I don't really have the contents of ComboBoxes and the like dynamically changing -- they are populated once only via databinding, so perhaps I should go back and change them to something with (possibly) less overhead?
Dave
@D. Matsumoto: If you KNOW that the items will never change, you might as well just use a List<T> - but if you may, at some point, decide to add/remove items from your list, I'd just use an ObservableCollection<T>. Most of the "overhead" is really only an issue when things change, in which case, you want the extra overhead...
Reed Copsey
Don't break MVVM for fear of possible overhead. Premature optimization...
Aviad P.
Sounds good, guys!
Dave