|
Oh dear. Oh dear indeed.
This space for rent
|
|
|
|
|
OK, I'm going to dive in here and expose my ignorance. I'm quite new to MVVM -- been working with it for less than a month -- and I understand the objectives of "Separation of Concerns", but it is not obvious to me why this code is facepalm. Could you walk me through an example of how this particular design might cause problems down the line?
On a similar note, I was recently describing "pure MVVM" to a colleague and I found myself struggling to provide a compelling reason to avoid all code-behind. He asked, "what difference does it make if I bind to objects in the code-behind rather than to objects in a separate 'ViewModel' class?"
Troelsen's sixth edition of "Pro C# 5.0" (published in 2012) has 3 or 4 chapters on WPF, but doesn't even mention MVVM or ViewModels, and instead puts all code in the codebehind. Help me understand why this is so problematic.
|
|
|
|
|
The "justification" of these patterns had a lot to do with the notion that we could have "visual designers" (who "can't program") and programmers (who "can't design UI's") work together to create an application.
The visual designers create the "views" (i.e. using Blend); the programmers create the view-models and models; and everything magically comes together.
In reality, the visual designers do their own thing using PhotoShop; using features that won't import into Blend; and having no appreciation for the "patterns" that have been established by the MVVM community; i.e. simplistic LOB (line-of-business) CRUD views (create; read; update; delete).
So, MVVM adherence is directly proportional to the numbers of developers on a project, the simplicity of the (LOB) app, and the fanaticism of whomever is the resident MVVM champion (if there is one).
(There is a reason why the many galleries of MSDN programming examples only feature MVVM as another "example": because they are not "typical").
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
modified 2-Feb-17 12:19pm.
|
|
|
|
|
Okay, the thing it sounds like you're struggling with here is what the concept of the ViewModel is in MVVM. The VM is, basically, the glue between the view and the models and allows you to "shape" the interactions from the views. Part of the reason to separate it is that you can more easily change what the View looks like and how it interacts with the models. By models, I'm talking about anything that isn't a view object - this could be writing to a log file, saving data to a database, reading files from the disk, and so on. Now, the biggest advantage of separating out the VM is, as you noted, Separation of Concerns, but this is best coupled with unit testing. In other words, having a ViewModel makes it a lot easier to test the behaviour of logical areas of code in isolation - typically, you'd have your models injected into your VM as interfaces which could easily be mocked. This is a lot harder to do in code behind - it's a whole lot harder because IoC isn't directly supported in creating windows and user controls.
Okay, that's fairly high level but here's one of my favourite advantages with the VM approach. There's an MVVM concept called ViewModel first - this talks about how you want to compose a particular view onto the UI. I shall apologise in advance for this because this is going to assume a lot of knowledge, but I shall try to simplify it where possible. With VM first, you put a plain vanilla Control onto your UI then you populate the template of this based off a binding. What this means is that you say that the control accepts a Binding of a type. Then, at runtime, we populate this with a ViewModel - this population might be driven by choosing to show a particular document type off a menu (for instance), and each document type is a different ViewModel. At this point, through the magic that is WPF, it looks for an appropriate template to display in the control. If we haven't associated a particular template (it's a DataTemplate I'm talking about here) with the ViewModel, it looks back through the inheritance chain of the ViewModel until it finds a matching template - the default one you'll see just displays the name of the class. If we have created a DataTemplate that matches the ViewModel, that particular template will be rendered in the control.
So, ultimately, the ViewModel approach allows us to decouple what the View looks like, from the behaviour of the control.
I hope that helps (and as a shameless plug, I have recently started a series of articles that aims to demystify MVVM and explain the whys and wherefores of it without any of the misconceptions that exist around it, you can find the articles here[^] and here[^])
This space for rent
|
|
|
|
|
That first paragraph makes perfect sense. I don't think I have quite enough foundation to grok that second paragraph, but I look forward to reading your articles. Thanks for taking the time to respond!
(I also just watched a fantastic video by Jason Dolinger that reiterates what you said and clarified a lot for me.)
Thanks again!
|
|
|
|
|
I've just bookmarked those two articles for later reading
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C.A.R. Hoare
Home | LinkedIn | Google+ | Twitter
|
|
|
|
|
Excellent. I'm deep in the process of writing part 3 right now. In order to demonstrate the power of templates, I'm rewriting the code so that it's capable of doing ViewModel first resolution.
This space for rent
|
|
|
|
|
Great stuff. I'll be sure to keep my eye out for that
"There are two ways of constructing a software design: One way is to make it so simple that there are obviously no deficiencies, and the other way is to make it so complicated that there are no obvious deficiencies. The first method is far more difficult." - C.A.R. Hoare
Home | LinkedIn | Google+ | Twitter
|
|
|
|
|
I have seen a lot of bad implementations of using MVVM. I know when I first started I was not as comfortable, and part of it is that Microsoft did not really provide the support of the product natively. One of the big problems is that when Microsoft released WPF they did not include much in the way of support for MVVM. In particular there was the ICommand interface where really needed some support, or had to roll your own. It would have been real nice for Microsoft to have inherent support for MVVM and WPF. Still whenever I create a sample project for CodeProject, I have to include some sort of ICommand implementation. Something on the order of MVVM Light would have been really nice, and then there would be lots of samples to use. Microsoft does provide PRISM, but it is not inherent, and seems to be overkill for simple projects.
|
|
|
|
|
Correct, RelayCommand and ViewModelBase are still copied somewhere from the webz... I've seen people using WPF controls in the Windows Forms way - doing everything with event handlers in the code behind files (and I admit: I started so, too).
But the more important point here is absolutely independent from that: it is the separation of UI and other logic.
|
|
|
|
|
I've seen WinForm Controls being passed to the business and data layers and I've seen direct database access in forms.
Nothing surprises me anymore
|
|
|
|
|
if one separtes the ViewModels in another class-library and don't use UP dependencies there (e.g. I use portableclass libs where you can't use UI .NET libs)
such things can never happen, maximum separation, maximum reuse... But have a look at MS examples, they could realy show how to do it right - not "simple" and wrong...
|
|
|
|
|
MVVM is incredibly difficult to get right and even after 8 years of tinkering with it I'm still learning! Some developers don't have the time, patience or permission to waste time getting it just right, when going to the code behind gets the job done.
I found the learning curve for WPF/MVVM incredibly steep and I'm sure that puts off many beginners. Part of that learning was the realization that MS put WPF out there half-baked and then moved onto something else. I find that over the years I've collected or developed so much code that could have easily been rolled into the framework at some point.
I find XAML particularly obtuse and difficult to work with at times. If I could change or improve two things with WPF it would be to simplify the XMAL syntax and dependency properties - the real place where 'code behind' should go.
It is such a shame that this technology isn't as accessible as Winforms because it can be incredibly powerful. Then again, maybe MS should admit that really the way to go is HTML5/CSS and simply replace what XMAL does with that. Unless (I'm not quite up to speed with Universal Apps) there is something already for that?
|
|
|
|
|
UWP APPS = evil
There's a very good reason why folks download Win7 CALC & Spider Solitaire.
Download the CALC & install on Win10, then run both side-by-side
|
|
|
|
|
Any UI code or references inside a viewmodel stinks, is ugly, and is totally unnecessary with good MVVM design, especially in WPF.
|
|
|
|
|
Then there is "business logic" and there is "plumping".
Is it necessary to note there is a difference?
I find it amusing that someone will spend "days" trying to avoid writing a single line of "code-behind" when confronted with a pattern that may deviate from your typical "view binding"; even if it has nothing to do with "business rules".
The "user" doesn't care that your idea of MVVM is "purer" than someone's else's; they're concerned you're spending all your time on "fringe" cases instead of solving their "business" problems.
"(I) am amazed to see myself here rather than there ... now rather than then".
― Blaise Pascal
|
|
|
|
|
Have you ever used the decorator pattern? I use to love MVVM - but IMO decorator pattern kills it every time for ease of use and clarity and most importantly making changes and upgrades for future features.
|
|
|
|
|
So apparently:
UWP = evil
WPF = half-baked and too steep of a learning curve.
WinForms = too old and obsolete
Now what?
|
|
|
|
|
Dennis_E wrote: Now what? 42
M.D.V.
If something has a solution... Why do we have to worry about?. If it has no solution... For what reason do we have to worry about?
Help me to understand what I'm saying, and I'll explain it better to you
Rating helpful answers is nice, but saying thanks can be even nicer.
|
|
|
|
|
|
bool isOffset = new bool();
if (reader["foo"].ToString().ToUpper().Trim() == "BAR")
isOffset = true;
else
isOffset = false;
I'll stop now.
Marc
|
|
|
|
|
Please, for the love of bacon, STOP POSTING THIS CRAP!
|
|
|
|
|
Dave Kreskowiak wrote: Please, for the love of bacon, STOP POSTING THIS CRAP!
It's about the only way that I can stay sane. Thank goodness I have TW&TW as an outlet for my pain.
Marc
|
|
|
|
|
Marc Clifton wrote: It's about the only way that I can stay sane.
Cheech and Chong may have something to help with that.
Wait a minute. For some reason I can hear Tommy Chong's voice when I read that code. Sounds about right.
|
|
|
|
|
Too bad he/she(it?) didn't have "bar" in the initial quotes. Then you could have replaced the construct with
bool isProgrammerCompleteFnIdiot(true);
Sudden Sun Death Syndrome (SSDS) is a very real concern which we should be raising awareness of. 156 billion suns die every year before they're just 1 billion years old.
While the military are doing their part, it simply isn't enough to make the amount of nukes needed to save those poor stars. - TWI2T3D (Reddit)
|
|
|
|