Nix
Nix

Reputation: 321

MVVM design pattern problems

I'm new to WPF and MVVM and am struggling a lot with how to design my app (hence lots of questions on here) and am about to do a refactor. I've got a SQL backend and am using LINQtoSQL so the classes that LINQTOSQL generates will be my model. I have yet to see a good comprehensive example of how to keep the model classes away from the view - in the example I'm looking at now a view is binding to ModelClass.Something instead of having a ViewModel property which references ModelClass.Something. Am I correct in thinking this is bad (if that field changes in the db the View breaks)?

What I'm struggling with at the moment is dropdown lists. Example: I have a lookup table called MessageType with an id and text field and a repository method to fetch them. So in my view I want to avoid binding the DisplayMemberPath and SelectedValue path to fields on my Model's MessageType class so do I need to make a new class and expose that class's properties in my ViewModel? Like this:

public class MessageTypeViewModel : ViewModelBase
{
    public MessageTypeViewModel(MessageType t)
    {
        MessageTypeText = t.messageTypeText;
        MessageTypeId = t.messageTypeId;
    }
    public string MessageTypeText { get; private set; }//bind DisplayMember and SelectedValue to these properties
    public int MessageTypeId { get; private set; }
}

populating like this:

get
{
if (textMessageSelectionOptions == null)
    {
        var list = repository.GetMessageTypes().Select(x=>new MessageTypeViewModel(x)).ToList();
        textMessageSelectionOptions =new ReadOnlyCollection<MessageTypeViewModel>(list);
    }
return textMessageSelectionOptions;
}

Also I have a Mission object that has a foreign key to MessageType so how do I bind the combo box's SelectedItem to mission.MessageType given that I now have this new class? I'm really struggling to get the pattern with the mission object, its children and its parents and I can't find any comprehensive examples where people are doing CRUD operations with MVVM. Am I going over the top or missing something?

Upvotes: 3

Views: 424

Answers (3)

Jay
Jay

Reputation: 57969

It seems like your MessageType is really an immutable value type, so I don't think the view-model is necessary.

Assuming you are working with a view that is bound to something like a MissionViewModel and there is a dropdown you want to populate with MessageType options bound to the property for which you've shown the getter, I think what you are doing is fine.

Populating the drop-down list with MessageType objects (by binding to ItemsSource) should by default display the result of calling ToString() on each item. If that does not give you the results you desire, you could go with the view-model or maybe create an IValueConverter implementation to display what you want.

If you have view-models in your drop-down instead of the MessageType objects themselves, then you can bind mission.MessageType to SelectedItem by using an IValueConverter to convert the view-model to MessageType. To perform this conversion, you can

A. expose the underlying MessageType as a public property of the view-model,
B. make the view-model itself implement IValueConverter so the conversion operation can access the private MessageType field, or
C. create the IValueConverter as a nested class of the view-model, again so it can access the private MessageType field

One downside to option B is that you'll need a public parameterless constructor to add the converter in a XAML ResourceDictionary.

Upvotes: 1

Ivan Karajas
Ivan Karajas

Reputation: 1101

The goal of MVVM is to make your application more maintainable, and save you from having to spend lots of time debugging tightly-coupled spaghetti code. If a pure implementation of the MVVM pattern achieves this for you, then it is worth your while to apply it fully. On the other hand, if you spend a whole lot of time writing ViewModel proxies for your model classes, but your application is small and won't be changed much once it's finished, a purist approach to MVVM might be overkill.

If you want to avoid exposing the model to the view entirely, you're probably going to have to create a ViewModel-specific version of your model and replicate all of the dependencies (e.g. Mission -> MessageType) while you're at it.

You might find this article useful: http://msdn.microsoft.com/en-us/magazine/ff798279.aspx, especially the section on collections.

Upvotes: 3

daryal
daryal

Reputation: 14929

You neeed to employ commanding instead of directly accessing from view from viewmodel or vice versa. Refer to WPF Apps With The Model-View-ViewModel Design Pattern

Upvotes: 0

Related Questions