ObservableQuery for Silverlight? - silverlight

Using ObservableCollections with Silverlight works great, because the UI is automatically updated when the data changes. But what if I am displaying a whole number of different views of the data, represented as different IEnumerable LINQ queries? My current approach is to have the DataContext implement INotifyPropertyChanged, and register for the backing collections CollectionChanged event, and fire the property changed event accordingly.
However, this is sort of repetitive to do over and over again. What I really want is an ObservableQuery that combines a query and an observable data source. Does this exist already? If not, what do I need to do when rolling my own for Silverlight to treat it the same way as an ObservableCollection? Is having a CollectionChanged event sufficient?
(I am most interested in Silverlight for the Windows Phone 7.)

What you describe doesn't really exist as such, but if you pass your IEnumerable<xx> into a CollectionViewSource (edit) you can get a few of the features decribed. This how ever does not fit so well with a ViewModel type pattern since you have to pull some leavers manually to make it work.
Another option is to take a quick look at the Reactive Framework. It's currently CTP (or maybe beta), but is also implemented for SilverLight. This gives you a LINQ querieable, IObservable<xx> Observable Stream or Collection (not to be confused with the ObservableCollection), that is basically an asynchronous, "push" version of IEnumerable .
It works very well with slow data loading into UI over a long period of time. You can can e.g. convert events into an observable stream, and start your LINQ query from there ect..
Check out this exellent Ch9 video w. Wes Dyer explaining how to use it with UI:
http://channel9.msdn.com/Blogs/J.Van.Gogh/Writing-your-first-Rx-Application

Related

WPF resetting DataContext to refresh binding

I have a project that gets data from a database and binds that data to some elements in xaml. I have added a button that fetches new data from the database and want to refresh the data bound elements in the xaml.
Now, I know the proper way of doing this is to implement the INotifyPropertyChanged events in the data class but I wanted to avoid this as there are so many properties. I figured out that simply calling 'this.DataContext = data;' after I have retrieved the new data from the database updates the binding in xaml.
Can anyone tell me what is wrong with this method?
Thanks!
Quite simply, if you don't want to implement the INotifyPropertyChanged interface, then don't use WPF. WPF is quite often a verbose language... it took me a while to get used to this. While there are mechanisms like Converters, Styles and Attached Properties that enable us to reuse code, you will often find yourself writing code that you've written before. Just get used to it, or change languages.
To summarise, you can't write effective applications in WPF without implementing the INotifyPropertyChanged interface.
If you don't use INotifyPropertyChanged interface you don't allow the binding mechanism to work since it wont know of any changes of your data.
The data binding is one of the most powerful tools in WPF if you dont use it you will have to write the propagation of the data changes between you model and the UI yourself like it was done in Winforms....
if its too hard to write the implementation for each property of each class in your than you can create a code snippet.. like prop/propdp

DataGrid and MVVM with Undo/Redo

I'm playing with quite simple interface with buttons and shortcuts for adding, inserting and removing rows of datagrid (underlying bound collection).
There's also a need to implement undo stack.
But...I have no idea how to do with internal logic of this control.
By default DataGrid can remove or add new row automatically and performs many other things on user input (Esc,F2 and so on) thus implicitly changing the bound data.
As commands are to be executed on the VM side undo stack is its (or even M's) business either, yet DataGrid contains internally predefined bindings to DataGrid. commands. And I see no easy mean of 'watching' the changes to the data.
My understanding of the ideal MVVM flow is like that:
User action (View) -> Command (VM) -> Commmand Excution + Undo stack operations. (VM-M)
-> UI changes respectively to VM changes.
I'm confused and need some good advice concerning the implementation.
2 Ways to go about this:
Have your all logic on the ViewModel (POCO Models).
You'll have to have your ViewModel contain an Undo/Redo stack. How you implement it is up to you, but I'd suggest just having the Undo/Redo stacks be of Tuple<String, Object>. Store the property name and the value of the property. It's easier than managing clones. It also gives you the ability for a poor mans "dirtiness" check by seeing if the UndoStack has any items on it.
Give your models some interfaces such as IUndoRedo (Rich Models).
You'll have to have your ViewModels call interface methods to Undo/Redo, but the idea is the same... have an Undo/Redo stack that is composed of Tuple<String, Object>.
If you do decide to want to have a rich model approach, you can look at existing frameworks out there such as CSLA.Net which is made for rich models, though it might be a bit more than what you'll really need. Just throwing it out there in case you want to have really rich models.
A side note: You're ObservableCollection (ItemsSource) should be of ViewModels, not Models. Just throwing that out there in case you were using the Models. That is, don't do ObservableCollection<IEmployee>, but rather ObservableCollection<EmployeeViewModel>. It makes things easier, much easier and more reusable!
Another side note: try to avoid the DataGrid. It makes developers wanna rip their hair out. I'd just roll out your own "Grid" with ListView :)
Normally I build the undo logic into the models themselves. Get them completely working the way you want before you even start thinking about how they are going to be bound to the UI.
I have done an article about undo / redo in MVVM. It is divided in two parts: the first explains undo / redo in general editions and the second explains working with lists:
Part 1: Using the Viewmodel pattern to provide Undo / Redo in WPF
Part 2: Viewmodelling lists
The flow is: User action (View) -> Command (VM) -> Commmand execution modifies the Model -> Model notifies changes to VM -> VM notifies changes to the view.
This way if the model is modified from other source it also refresh the view.
There is also a github project here.
Since your DataGrid is bound to a collection, you can monitor changes to the Collection itself instead of the DataGrid. Use the CollectionChanged event on your collection to watch for added or removed items, and register a PropertyChanged event on all of your collection's items for monitoring edits.
An alternative idea would also be to provide a RevertChanges command instead of UndoChanges. Its much simpler to implement because you only need to store the original collection so you can restore it if needed.

Custom property dependant on other properties

Advance apologies for the event-style explanation; there's a lot of factors that I feel all play a role of their own. WPF is not my native framework of choice, and it probably shows. :)
Old situation: I had a window with several controls. Depending on their selections, I used multibindings and a converter to determine whether certain controls needed to be shown that inform the user about the implications of their changes before they'd eventually confirm them by OK (or simply dismissed by using Cancel). This worked perfectly.
Problem: Too many controls as time went by, too much clutter.
Solution: Put stuff in different Pages so it becomes easier to browse for the user. In order to have changes-to-be persist as a user arbitrarily browses between the pages, I create these dynamically and put them in a cache (Dictionary<string, BasePage>, see below), from which they will be pulled as the user chooses them.
Consequence: I need to decouple the bindings to the notification controls as the different options are now on different pages.
Solution? I put a BasePage class in that exposes certain abstract read-only properties that define the various aspects that the window needs to know about in order to do its notifications. For example, a bool requiresReboot property defines whether the current state of things on that page requires a reboot to take (full) effect. A specific page implements the property based on its controls.
Problem: I do not know how to keep create a proper binding that properly gets updated as the pages are changed. I tried giving my notification controls a binding to the Dictionary<string, BasePage> with a converter that checks all pages and the relevant property.
Questions:
1) How do I create a proper property for this purpose? I presume I need a DependancyProperty as I did a fair bit of reading on MSDN, but I can't figure out how this fits together.
2) How do I make a link between my custom property so that it allows (multiple) control(s) on a page to change that property? Do I use INotifyPropertyChanged somehow? My old example bound against several CheckBox.IsChecked properties in XAML. I am trying to avoid putting tons of events (OnChange, etc) on the controls as the original code did not need it and I have been told it makes for a messy solution for as far WPF is concerned.
3) Finally, I suspect I may need to change my Dictionary<string, BasePage> class to a custom implementation that implements some sort of INotifyPropertyChanged but for Collections? Observable Collection is the term I am looking for, I believe.
I hope someone is able to bridge the gap in my understanding of WPF (property) internals; I would very much appreciate it. A basic sample would be even better, but if it is too complicated, just a nudge in the right direction will do. Thank you. :)
It's been a while since I solved this, and while I cannot remember the exact cause of the problems, there were a few different issues that made up the bulk of the trouble I ran into.
I ended up making the Property in question a non-abstract DependencyProperty in the base class; it was the only way in which I could properly delegate the change notifications to the interface. Derived classes simply ended up binding it to their controls (with a proper Converter in the case extra logic was necessitated).
As Dictionary<string, BasePage> does not support any sort of change notification, I made an extra collection of ObservableCollection<BasePage> which I used for binding purposes.
However, such a collection does not propagate a change event when items inside of it has a property changed. Since this situation required that, and I was binding to the collection itself in the context of a property that does not have a Master<->Detail relationship like a DataGrid (which basically add their own OnPropertyChanged handlers to the binded object), I ended up subclassing a VeryObservableCollecton<>. This one listens to its own items, and throws a proper change event (I think it was an OnPropertyChanged from the INotifyPropertyChanged interface) so that the binding (or in this case a multi-binding) would refresh properly and allow my interface to update.
It is hardly the prettiest code, and it feels over-engineered, but at least it allows me to properly bind the UI to the data in this manner.

WPF: Binding with nonstatic parameter? (newbie question)

This will probably be obvious but I can't find the best way.
I want to show the user's ToDo's in a listbox. These ToDo's are in the database and consist of an Id, UserId and Description.
The user logged in to the app.
How can I retrieve the ToDo's for that certain userId and set it up for binding to the listbox?
I was trying with an ObjectDataProvider but I cant figure out how to use that in combination with nonstatic stuff (like my _dbService, userId, language, ...).
Are the only options to make all those things static versus binding in the code behind?
If so, this means that ObjectDataProvider isn't very useful, no?
I find a lot of examples of it being used with a hardcoded parameter but I hardly see any situation where I'd need such a functionality..
I do all my WPF using the Model-View-ViewModel pattern. I've given you one link there but Google will give you loads. MVVM seems to be the standard pattern for WPF. This project is probably more complicated than you need but it is well-written and brings home the use of MVVM.
Basically, you create a Model of your data. In this case, you'd probably create a simple class (I'll call it ToDoItem) with properties Id, UserID and Description. Use your preferred mechanism to get a collection of these from the database. Link to SQL, Entity Framework, a standard query, whatever.
Then you have your ViewModel - you have an instance of the ViewModel for each instance of the Model: the VM has a reference to the M and 'forwards' properties to it. The ViewModel is what you use to manipulate the model.
Then you have your View - this is the UI. You set the DataContext of the View to be the ViewModel and then your bindings automatically bind to the ViewModel. Your View just ends up being the things you can see. All of the work gets done in the ViewModel. This means it's very easy to test.
So, when you click on a button in your View, the bindings pass this onto a Command in your ViewModel which manipulates the Model.
The UI is also a View with a ViewModel. So, your UI VM might load a collection of Models from the database and stick them in an ObservableCollection. The ListBox items collection would be bound to this ObservableCollection.
It's hard to explain all of this in a post like this. Read a couple of articles and see what you think. I'm still quite new at this, too, but I believe my reading about MVVM has paid off.
Hela Thomas, Tom here from Orbit One :)
MVVM is the way to go. I'm on my 4th project and WPF really shines if you use mvvm. You already tried MVC (or MVP as we did on recy*tyre) and that's a nice separation of concern.
MVVM takes it a step further since the viewmodel knows absolutely nothing about the view.
The view binds to the viewmodel, so it has a reference to it (2 way, super powerful and works beyond the typical MS demo). The viewmodel is just a poco and is a representation of your view, data + behaviour. Once you dig this paragraph the cool term mvvm will have no secrets.
I see if I can come up with a small demo. Maybe I'll have time later.
What I will come up with is a view (xaml, file 1) that binds to a viewmodel (file 2, a poco class, not to be mistaken with code behind). The model can be whatever you like (service layer or directly to the repositories). Using the power of 2 way binding we will bind to an observable collection meaning that if we add/delete/... something to the collection the view will pick it up without us putting energy into it.
My first 2 wpf projects was done with Caliburn Micro (see codeplex) which is a powerful framework based on conventions. It shields you away from hardcore wpf (creating tour dependency properties yourself mainly) and you can create something relatively fast without fully understanding wpf. That's a downside of itself but it worked for me. As of project 3 I started taming those dependency properties myself and it will make you a better wpf developer.
I see the question is from October.. did you find a good solution?

How can WPF Converters be used in an MVVM pattern?

Let's say I have a View that is bound to ViewModel A which has an observable collection Customers.
An advantage of this MVVM pattern is that I can also bind the View to ViewModel B which fills it with different data.
But what if in my View converter Converters to display my customers, e.g. I have a "ContractToCustomerConverter" that accepts a Contract and returns the appropriate Customer to be displayed.
The problem with this is that the converter exists outside the MVVM pattern and thus doesn't know that my ViewModel has another source for customers.
is there a way for the View to pass the ViewModel into the Converter so that it participates in the decoupling that the MVVM pattern provides?
is there a way for me to somehow include the Converter in my ViewModel so that the converter uses the current dependencies which ViewModel has available?
or are converters just glorified code-behind and thus not used in the MVVM pattern, so if you are using MVVM then you just create your own "converters" (methods on your ViewModel class) which return things like Image objects, Visibility objects, FlowDocuments, etc. to be used on the view, instead of using converters at all?
(I came upon these questions after seeing the use of Converters in the WPF demo application that comes with the MVVM Template Toolkit download, see the "Messenger Sample" after unpacking it.)
I usually don't use converters at all in MVVM, except for pure UI tasks (like BooleanToVisibilityConverter for instance). IMHO you should rather declare a Customer property of type CustomerViewModel in your ContractViewModel, rather than use a ContractToCustomerConverter
In this conversation there is a comment that agrees with Kent's position, not to use Converters at all, interesting:
A ViewModel is basically a value converter on steroids. It takes "raw" data
and converts it into something presentation-friendly, and vice-versa. If
you ever find yourself binding an element's property to a ViewModel's
property, and you're using a value converter, stop! Why not just create a
property on the ViewModel that exposes the "formatted" data, and then drop
the value converter altogether?
And in this conversation:
The only place I can see a use for
value converters in an MVVM
architecture is cross-element
bindings. If I'm binding the
Visibility of a panel to the IsChecked
of a CheckBox, then I will need to use
the BooleanToVisibilityConverter.
Converters should rarely be used with MVVM. In fact, I strive not to use them at all. The VM should be doing everything the view needs to get its job done. If the view needs a Customer based on a Contract, there should be a Customer property on the VM that is updated by VM logic whenever the Contract changes.
An advantage of this MVVM pattern is that I can also bind the View to ViewModel B which fills it with different data.
I dispute that claim. In my experience, views are not shared across different VM types, and nor is that a goal of MVVM.
For those effectively saying no "non-trivial converters" in the view, how do you handle the following?
Let's say that I have a Model of climate sensors that represents time series of readings from various instruments (barometer, hygrometer, thermometer, etc.) at a given location.
Let's say that my View Model exposes an observable collection of the sensors from my Model.
I have a View containing a WPF Toolkit DataGrid that binds to the View Model with the ItemsSource property set to observable collection of sensors. How do I represent the view of each instrument for a given sensor? By displaying a small graph (think Edward Tufte sparkline here) that is generated by converting the time series to an image source using a converter (TimeSeriesToSparklineConverter)
Here is how I think of MVVM: The Model exposes data to View Models. The View Model exposes behavior, Model data and state to View. Views do the job of representing Model data visually and providing an interface to behaviors consistent with the View Model state.
Thusly, I don't believe that the sparkline images go in the Model (the Model is data, not a particular visual representation of it). Nor do I believe that the sparkline images go in the View Model (what if my View wants to represent the data differently, say as a grid row just showing min, max, average, standard deviation etc. of the series?). Thus, it seems to me that the View should handle the job of transforming the data into the desired representation.
So if I want to expose the behaviors, Model data and given state for a certain View Model in a command-line interface instead of a WPF GUI, I don't want my Model nor my View Model containing images. Is this wrong? Are we to have a SensorCollectionGUIViewModel and a SensorCollectionCommandLineViewModel? That seems wrong to me: I think of the View Model as an abstract representation of the view, not concrete and tied to a particular technolgy as these names suggest they are.
That's where I am in my continually evolving understanding of MVVM. So for those saying not to use converters, what are you doing here?
I've been using Stackoverflow for years and this is accrual my first answer posted.
I think converters belongs to View in MVVM, consider the following situation:
App is developed by 3 teams, webapi team, webclient team and UI team. UI changed frequently so the webclient team (which receives data from webapi and put them into viewmodel) cannot always modify the viewmodel to satisfy UI needs. This becomes impossible when the UI team have different versions of design. So the UI team must have their own way to present the data and the solution is Converters.
Hope this helps someone.
I'll add my 2 cents to this discussion.
I do use converters, where it makes sense.
Explanation:
There are cases where you need to represent 1 value in Model in more ways in the UI. I expose this value through 1 type. The other is type is handled through converter. If you were to expose 1 value through 2 properties in VM, you would need to manually handle update notifications.
For example I have a model with 2 ints: TotalCount, DoneCount. Now I want both this values to be displayed in TextBlocks and additionally I want to display done percentage.
I solve this using DivisionConverter multi converter which takes 2 previously mentioned ints.
If I were to have special PercentDone in VM, I would need to update this property whenever DoneCount is updated.

Resources