Detecting DataContext changed in Silverlight - silverlight

I have a multi-part question:
(1) Is there a good reason why Silverlight doesn't expose a DataContextChanged event? It seems like a whole lot of hassle could be avoided if someone at Microsoft just changed internal to public in the FrameworkElement class (like WPF does).
(2) I've found one or two different methods for hacking your way into a DataContextChanged event by using DependencyProperties in one configuration or another. But I can't get them to work reliably. My testing so far seems to show that they fire the hacked DataContextChanged event just fine for the first class to which I hook them up, but don't fire for any other classes. Has anybody else run into that problem? Or better yet, have they worked their way around it?
(3) The reason I've been giving myself for wanting to know when my DataContext has changed is that there are some UI operations that are complicated to get right in XAML, but are trivial in code-behind; and for many of those things, I need to handle events raised by my ViewModel; and hence I need to know when my ViewModel has changed, so I can wire up the event handlers. Is this an accurate view of the world? Or is the fact that I'm wanting to deal with this sort of thing in code-behind a pretty good indication that my thinking has gone off the rails some ways back? I'm no MVVM purist: I just want to get from here to good code quickly, and I don't particularly care how I get there. Code-behind has served me reasonably well for over a decade now, and I'm loth to abandon it entirely. But is my pragmatism making it harder on myself at this point?

"But is my pragmatism making it harder
on myself at this point?"
I wouldn't call it pragmatism. I'd call it fear of change; staying in your comfort zone. Life is actually far easier if you abandon your old way of thinking and embrace the new (and I know exactly what you mean - I was in the same boat as you with code-behind).
Now, off my soap box and to a more practical answer:
When you want to detect changes in your model, then hook into the events that allow you to detect changes in your model. The DataContext is not really the model... All of your model objects are going to have an implementation of INotifyPropertyChanged. You should either be hooking into that for a given model, or hooking into something similar for an ObservableCollection.
Silverlight/WPF make all of this sort of stuff WAY easier now that databinding actually works.
Don't fight the framework. Don't bring old ASP.Net practices with you to this game... It will not help you. You'll lose the best parts of the framework's power that way.
Cheers.

Related

Is it "Proper" for a Behavior to Act as a View Model?

Recently, in a WPF project, I created an attached behavior for a third party control in order to make it more MVVM-friendly. My initial approach was to bind it to the view model, which in turn was bound to other controls. However, after thinking about it, I realized that I could reduce the overall amount of code if I simply made the Behavior itself the data context for some of the other controls. I tried it, and it works fine. While this approach seems unconventional to me, I honestly can't think of any real objection to it. So does this still conform to MVVM etiquette? Any opinions?

MVVM best practice around view logic in Silverlight

I am trying to get into MVVM and away from the code behind approach in Silverlight, and I want to know the best practices around how to invoke view logic.
I have a very basic page where I have bound a listbox to a collection of domain objects, this is all using MVVM, so when I recieve my data back from the services, I want to fire off an animation and view changes on the screen.
Where/How is the best way to doing this? Silverlight (version 3, BTW) doesnt have triggers does it? I have seen blogs where people seem to be using them, but i think they must be rolling their own? Not sure... anyways, any thoughts ideas here is greatly appreciated
First of all, I think code behind is just fine as long as it only works with the view, i.e. it is concerned only with UI concerns. Don't struggle for no-code-behind when the easier way out is just as correct.
Secondly, of course sometime you need some sort of disconnected communication between your view and view-model (for example, getting multiple selected items from your view into your view-model). For these purposes you could use an aggregator like MVVMLight's Messenger, which is both simple and expresses the concept nicely. You can send a message from the view-model and have the view listen for it; also you can send messages from your view (when some events occur) and broadcast them.
MVVMLight also includes some utility classes which make it easy to bind events directly to Commands in your view-model, so that's the easier option in most cases I think.

wpf databinding testing

I'm in the process of learning WPF, where one of the strong suits is supposed to be data binding. When I do a win forms app, because I don't trust data binding much, I use what Fowler would call an assembler and just do it by hand, which makes it easy to test also.
I've read Jeremy Miller's blog enough to see he has issues with data binding too (even with wpf), and circumvents it, but I never did see a clear example of how he does it.
I do like what I see so far with wpf's rendering and layout capabilities, but I'm just not sure about the MS data binding technology. My question is does anyone have any reasons why data binding is so good in wpf you can easily separate concerns and test it, and if not, what is the basic idea you use as an alternative?
I don't want to speak for Jeremy, but I believe his beef with data binding is less about the binding itself, and more about how it results in hard to debug/test/maintain code. This is certainly true of WPF/SL when you include your bindings in XAML because they can break without you being aware of that until runtime (and maybe not even then). A nice fluent interface can make binding an absolute pleasure to write, debug, and maintain. It was one of my motivations for writing Truss.
However, doing your data binding in code can break the designer/developer collaboration. Blend doesn't execute code when designers open up a UserControl or whatever. Therefore, any bindings written as code will not be hooked up.
In an ideal world, we wouldn't be forced to choose between maintainability and designer collaboration. But that seems to be where things are at the moment.

Is MVVM really useful?

I have read the MSDN article on MVVM and I am not really convinced.
If the model already implements INotifyPropertyChanged/INotifyCollectionChanged, what's wrong with the View binding directly against the Model?
It seems the extra ModelView introduces some code without much benefit.
Am I missing something?
I was also a bit skeptical about MVVM until I watched this great presentation by Jason Dolinger. I recommend all my co-workers who are starting out in WPF and MVVM to watch it.
Jason started with an application that
one would write in a “traditional”
way, with button clicks handled by
event-handlers in the code-behind that
then updated other parts of the UI.
Using WPF data-binding, Commands, and
Unity, he transformed it, piece by
piece, in a much more manageable,
encapsulated, readable, and testable
M-V-VM design. It was awesome.
To answer your question more directly, even if it seems silly to bind to a ViewModel when your Model already has everything, you'll often wind up needing one little adjustment to the Model that's needed only by the View. Over time, these little changes will creep into your Models, where they don't belong. It'll make your models more complicated than they ought to be.
What I often do when I have a Model that "has it all", is I add a ViewModel that contains one property, the Model. Then in my bindings I just bind to Model.Name, Model.Age, etc. It's really no effort. Later on, if I need tweaks only for the View, I already have my ViewModel class ready. This also makes your code more intuitive and easier to understand. You won't wonder, did I bind to the Model or the ViewModel in this case? It will always be the ViewModel.
INotifyPropertyChanged and INotifyCollectionChanged are not the only aspects to be considered... In many cases, the data exposed by the model will not be easily usable by the view. The role of the ViewModel is to act as an adapter between the model and the view : expose the data in a form that allows the view to easily bind to it, expose commands to which the view can bind in order to perform actions... Typically, a model won't expose ICommands : if it does, then the model is WPF-specific, which is never a good thing is you want to reuse in some other non-WPF application...
I have been using MVVM for a few months, and it made my life much easier : no more "spaghetti code" in code-behind files, clear separation of responsibilities, clean overall architecture...
I have been using MVVM for 2 projects and here are a few things that I have been doing in the ViewModel:
Transforming the data from the model (When you are using a ViewModel, it makes life easier when UI specifications change, you don't need to change the Model/Persistence code)
Implementing a ICollectionView over a collection provided by the model
Implementing Commands
Caching (maintain expensive to calculate data)
Maintaining a dictionary on model data (for fast lookup)
Lazy-loading (not load until it's been used by the View)
Managing Undo/Redo
Validation of data (IDataErrorInfo)
and there is much more to do there (that I forgot) that would not fit in the Model itself, or would make the user interface spaghetti.
Not to forget, the ViewModel enable you to unit test things that you would not be able to test if it was implemented in the UI (such as Commands).
Finally, using MVVM, I was able to build a command-line version of my application very easily by using the ViewModels.
I'm using MVVM with MEF for a few years now and am not really sure how helpful it really is.
In our development we don't reuse ViewModels for different Views, neither do we have designers who are only allowed the change the View (UI).
And a lot of things are hard to achieve in a ViewModel, like setting the cursor focus depending on changes in the ViewModel (yeah, it is possible, but adds a lot of clutter to the code).
The good thing about MVVM is organising the values and commands as bindings instead setting the fields directly, but this could be done without the ViewModel.

Is there a performance hit for a Silverlight application while implementing MVVM pattern using Databinding?

I am implementing the Model-View-ViewModel (MVVM) pattern in one of the forms of my SL2 appication using INotifyPropertyChanged interface and TwoWay Databinding.
However I feel that due to this approach, my form behaves slightly sluggishly.
I just wanted to know whether using this approach is there any performance hit in such SL2 applications.
Thanks...
Sudeep
I have not noticed any slowdown. We are doing a LOT of binding to INotifyPropertyChanged ViewModels and the UI seems to be extremely responsive.
Sure, there will be a hit for data binding vs direct data access... but that hit is so small that the benefit you get from data binding makes the small hit inconsequential.
Something to remember: The data binding is happening in the UI. There isn't a lot of high intensity processing happening at that layer. In addition, the UI renders on a separate thread. Those two things together make for an experience that feels very responsive, in my opinion.
Erik asked if you have any Value Converters in place? I would ask the same thing. If so, are they doing a lot of work? In my experience with MVVM, value converters are rarely needed anymore. Just some food for thought.
I haven't noticed any slowdown. The Prism Reference Implementation, among many others, seems to be fast.
In fact, the binding system uses dependency properties. Just like the animation system. Part of the reason is that the values can be updated quickly by the framework.
Do you have any Value Converters in place?
We do a lot of MVVM with Prism and haven't noticed a performance hit. Quite the opposite - the app often demos faster than it's low-tech Windows counterpart.
Check as well in which places you need two way binding in which other just one time binding.

Resources