Reputation: 321
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
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
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
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