Displaying an XDocument as a WPF treeview using an MVVM ViewModel - wpf

I have XSD's held as data in a SQL Server XML, or oracle XMLtype field. I retrieve an XSD from the database as an XDocument. I want to display this XDocument in a WPF treeview. This is relatively straight forward if I bind the Xdocument directly to the treeview using an xmldataprovider and a hierarchicalDataTemplate.
However, my application is using the mvvm pattern and I would like to represent the xdocument in the ViewModel layer, which the treeview then binds to in a similar way to the Josh Smith article on binding the WPF treeview to ViewModels.
http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx
My goal is to select an XNode of the XSD (XDocument).
Any suggestions for how I could represent the Xdocument of an XSD in the ViewModel so that I can select an XNode?

If you're doing read-only operations, I'd recommend that you keep it simple and don't introduce new classes that provide no benefit. Just leave a comment that you should add a view model if you ever want to support editing the structure. Even if you want to be able to edit the document, you might still be able to bind to the document and nodes directly, depending on your needs.
If you need more advanced support (like INotifyPropertyChanged), I suggest that you create a hierarchy of classes like the original API, based on XObject. I would only add properties that I planned on directly supporting in the UI. I would then create a separate model class that could convert from the XDocumentViewModel hierarchy to a real XDocument, and back.
... how [to] represent the Xdocument of an XSD in the ViewModel so that I can select an XNode.
What do you mean by select?
If you mean in the UI, then that's taken care of in the XAML.
If you're talking about querying the view model, then you could try to use the existing LINQ XML querying API against the underlying document. Keep an internal dictionary mapping XObjects back to your view model objects, and when you get results, simply look up each result in the dictionary before returning it.

Related

Using Data sets in MVVM

What is the best practice to use data sets instead of an observable collection in MVVM to bind to grids. is it OK to have a property of type DataSet on the view model? How is the design time data set in this case?
One of the key concepts of the MVVM pattern is that the ViewModel is the "model of your view", it shapes your business model in such a way that it is easier to bind a UI (i.e. your View) to it.
You can certainly use a DataSet / DataTable to expose data from your ViewModel and bind it to your View. I don't see anything wrong with this approach. It is certainly valid MVVM!
Regarding design time data, it depends on how you are creating it. You cannot create a DataSet in XAML, so cannot use a XAML file within visual studio for your data. However, if you are programmatically creating design time data, i.e. within your ViewModel checking whether it is design-time, then creating data in your code, it will work just fine.

WPF listview, Load, Save & Add

I have a columned listview who's items I would like to store in an XML file.
What's the best way to go about loading, saving and adding items?
best way is to use MVVM :), that way your View simply represents the data in the UI. Actual DomainModel/BusinessObject resides outside your View.
And then you can use number of persistance methods:
XML Serialization
ORM (Object Relation Mapping), which will persist/save the BusinessObject into Database and back
Step by step way:
Create/Define your BusinessObject(DomainModel, i.e. Person class)
Use DataTemplate to Bind to Collection from your ListView
In your ViewModel, you can than say PersonCollection.Save/Load etc

Binding WPF control to multiple sources (not traditional multibinding)

I am trying to do some databinding magic. I have a Shipments view that lists shipments, and provides filtering and ordering ability on the list. The filter string box, Delivery Status filters (checkboxes) and Ordering Radiobuttons are databound to properties in the ViewModel. I want to add the ability to save state and I have elected to do this by saving control states in an xml document. Previously I have done this before with little problem, using databinding to just read/write the values back and forth.
However, now I have a quandry. My filter controls are currently databound to items in the ViewModel. i can write code that changes their databinding from the xml to the ViewModel on load and vice versa, but that would be messy.
Is there a mechanism in place that I can use to achieve the ability to bind to two equal sources and have them updated at the same time?
This sounds like a concern for the view model.
Why not load the saved values into the view model, and have the view model decide what data to expose?
Then the view doesn't have to be concerned with managing data.
None that I'm aware of.
My opinion: I really wouldn't do this anyway - if your datacontext is the viewmodel, and the viewmodel has properties for the filter, you almost certainly should be persisting and retrieving the relevant viewmodel state to keep the state of the filters. Trying to save controlstate, then retrieve it, set it, and set the viewmodel based on the new controlstate sounds like a lot more work and much more prone to bugs.

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.

ViewModel on top of XDocument

I am working on a WPF application which has a treeview that represents an XML. I load the XML on to the XDocument, then bind the TreeView to this object.
Now using the MVVM pattern, I want to provide a ViewModel on top of XDocument. What are some of the things that I should implement in the ViewModel class.
I am thinking of,
RoutedCommands that bind to ContextMenu commands on the TreeView to allow add node, remove node, modify node etc
Logic to actually modify attributes and nodenames on the view.
Am I going in the right direction? What else should I do to make it cleaner, modular at the same time easy to understand.
Should I use RoutedCommands or implement ICommand interface and create my commands?
How about using attached properties for CommandBindings? does it make sense to do it in the treeview app that I am talking about? I am a bit overwhelmed because of so many options available to implement this.
Does anyone have links, sample code that does this sort of thing? A reference implementation may be?
I'm with you. I started with
(ui) <-> (xml)
where xml represented as LINQy XElements so I got PropertyChange notification.
I then added some stateless helper classes to help me deal with xml (expose properties, validate data, etc). I'd bundle up XElements in ObservableCollections so I could bind to them.
Read about M-V-VM, and decided to convert my helper classes into ViewModels. Problems:
Helper classes live in the data model namespace which knows nothing about UI. Helper classes know how to convert database row into XElement, ViewModel should never see that.
Helper classes deal with xml. ViewModel shouldn't know or care.
So I'm actually considering implementing
(ui) <-> (viewmodel) <-> (helper) <-> (xml)
but i just balk at raising PropChange events in helper only to reraise them in viewmodel.

Resources