MVVM Blues...
-
I felt the same way when I first started MVVM, then I stepped back and reconsidered what the puropose of MVVM really is...To segregate your data and business layers from the UI. Read through this little example and you'll see my point at the end. Take for example double-clicking a list item. You want to know in the ViewModel what list item was double-clicked. You can bind the list's SelectedItem in the XAML to a property on the VM, but that handles clicking a list item, not double-clicking. To handle this, you need to handle the event. But that's not easy in MVVM. Here's what I do to handle something like this. In the View's code behind: First the XAML
Then in the code behind:
public MainPage()
{
InitializeComponent();
this.DataContext = new MainPageViewModel();
}then the event
private void ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
{
ListBox list = sender as ListBox;
ListItem item = list.SelectedItem as MyBoundType;var dc = this.DataContext; dc.ListItemDoubleClicked(item);
}
This assumes a method in your VM called ListItemDoubleClicked that accepts a parameter of the type bound to your list. The point here is this - you can write code in your views that references your VM becuase the view already knows aout the VM. Just don't write any data-related code in the view's code behind and you're not violating VMMV.
Everything makes sense in someone's mind
The whole point of MVVM is not to have code in your code behind. You want your view abstracted from the business logic as well as the data it is bound to. This approach of directly calling an event in the code behind, tightly couples everything. To conform more with mvvm, rather re-route the event through a command.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
You will need to download: System.Windows.Interactivity.dll for the expression blend sdk. To use this functionality. I do believe that design patterns should only be used as a guideline for better development. not to be followed so strictly. But in this instance there is a better more mvvm type of solution. To what you suggesting with eventing.
-
The whole point of MVVM is not to have code in your code behind. You want your view abstracted from the business logic as well as the data it is bound to. This approach of directly calling an event in the code behind, tightly couples everything. To conform more with mvvm, rather re-route the event through a command.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
You will need to download: System.Windows.Interactivity.dll for the expression blend sdk. To use this functionality. I do believe that design patterns should only be used as a guideline for better development. not to be followed so strictly. But in this instance there is a better more mvvm type of solution. To what you suggesting with eventing.
The whole point of MVVM is not to have code in your code behind I completely disagree. The point of MVVM, or any design pattern for that matter, is separation of concerns, not "no code behind". No where in this does is mandate that you cannot have code in the code-behind. And, the view is already coupled to the view model when you do
this.DataContext = new MyViewModel();
The code I posted did not make any reference to the business or data layers, so it did not violate the design pattern. However, I do like the code you posted and agree that a command is the way to go. I posted my snippet as an example of calling into the VM from the view. Like I said, the two are already coupled, and the code didn't reference data or the BL, so there's no reason not to do it.
Everything makes sense in someone's mind
-
The whole point of MVVM is not to have code in your code behind. You want your view abstracted from the business logic as well as the data it is bound to. This approach of directly calling an event in the code behind, tightly couples everything. To conform more with mvvm, rather re-route the event through a command.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
You will need to download: System.Windows.Interactivity.dll for the expression blend sdk. To use this functionality. I do believe that design patterns should only be used as a guideline for better development. not to be followed so strictly. But in this instance there is a better more mvvm type of solution. To what you suggesting with eventing.
In your example above, what is the "cmd" in
Thanks
Everything makes sense in someone's mind
-
The whole point of MVVM is not to have code in your code behind I completely disagree. The point of MVVM, or any design pattern for that matter, is separation of concerns, not "no code behind". No where in this does is mandate that you cannot have code in the code-behind. And, the view is already coupled to the view model when you do
this.DataContext = new MyViewModel();
The code I posted did not make any reference to the business or data layers, so it did not violate the design pattern. However, I do like the code you posted and agree that a command is the way to go. I posted my snippet as an example of calling into the VM from the view. Like I said, the two are already coupled, and the code didn't reference data or the BL, so there's no reason not to do it.
Everything makes sense in someone's mind
You just said it yourself separation of concerns. If your code is in the code behind how is it a separation of concerns than. Thus it is counter productive to what you trying to achieve out of the pattern. Yes I agree to an extent that you shouldn't ever follow a pattern completely and only see it as a guideline. However what you were trying to achieve can be done without hooking up an event and finding the selected item. Like I've said previously you can do what you were trying to do in a far cleaner way. As far as initializing the ViewModel for the DataContext. Well that can also be done in xaml. There are many ways to skin a cat remember that. The key is to find the most flexible solution when testing and going forward. The question I ask is what if you want to change your viewModel? you have to go into the code behind and instantiate another object. Why don't you rather use a IOC container in this scenario. So you can have a more decoupled soltuion. ;)
-
In your example above, what is the "cmd" in
Thanks
Everything makes sense in someone's mind
A light MVVM framework called Galasoft
xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
-
The whole point of MVVM is not to have code in your code behind. You want your view abstracted from the business logic as well as the data it is bound to. This approach of directly calling an event in the code behind, tightly couples everything. To conform more with mvvm, rather re-route the event through a command.
xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
You will need to download: System.Windows.Interactivity.dll for the expression blend sdk. To use this functionality. I do believe that design patterns should only be used as a guideline for better development. not to be followed so strictly. But in this instance there is a better more mvvm type of solution. To what you suggesting with eventing.
Dean Oliver wrote:
The whole point of MVVM is not to have code in your code behind.
That's not quite true. The idea in MVVM is not to have code that knows about the model in the code behind of the view. If you want to have code that handles something like a window resize, for instance (it's just an example, and yes you could perfectly easily accomplish this with attached behaviors), it's perfectly acceptable to have this in the code-behind; as long as it doesn't have any model knowledge.
*pre-emptive celebratory nipple tassle jiggle* - Sean Ewington
"Mind bleach! Send me mind bleach!" - Nagy Vilmos
My blog | My articles | MoXAML PowerToys | Mole 2010 - debugging made easier - my favourite utility