WPF: Problem with Hierarchy - wpf

I've noticed a problem I'm having depending on the Hierarchy of items. When I wan't to represent the items I have no idea how to put it's children in a manageable state.
Let's take a TreeView for example. When the window is loaded up I can take the model and put it into a view and as a source for the tree. However I seem to have no real control over the children. Only thing I can do is point to the children property of object and it shows up all real nice but what if I wan't to edit, sort and/or add a new item there I'm out of luck.
I can't really put the children into the view or a seperate collection to modify as they are only the property of the root element. Only way I can see at the moment is having the property return a ObservableCollection or a CollectionView and that has it's own problems as in no lazy loading for example.
How are you doing this, what is the proper way here and what am I missing?

Related

Is it correct to let the viewmodel add children to its view?

Im currently learning about the MVVM pattern in WPF. I think it is really cool but my question is: is it correct to use the viewmodel directly for appending children to its view?
For example lets assume we had a method which contains a loop which adds new rows to a grid when a button is clicked. Should my ViewModel only contain pure data or can it also contain logic for placing new elements on the field? As well as removing them.
is it correct to use the viewmodel directly for appending children to its view?
No. The view model shouldn't know about any view elements.
Should my ViewModel only contain pure data or can it also contain logic for placing new elements on the field? As well as removing them.
The former. The view model may expose a collection of data objects that the view happens to display in a Grid. Or some other kind of panel. The view model doesn't care about which.
You would typically use an ItemsControl in the view to display the items in a view model collection, i.e. the ItemsControl binds to the source collection and displays a visual representation of each item in a panel.

Hide Elements in WPF TreeView

i have the following scenario:
I have a ViewModel with hierachical elements to display in a TreeView. So far so good. What i want to do now is hide/remove elements from the TreeView according to some property set on a ViewModel-Element, like IsConfigurable or such.
If i disable die DataTemplate, the element is removed, but also all child-elements, which is not what i want.
Is that even possible?
Greets,
Jürgen
That sounds somewhat strange, but nevertheless...
You should consider that your application shall remain test and debuggable.
Your model contains the orginal data (collection) as it is - no meddling here. In your ViewModel, the object that you are binding to, you can calculate the transformation as you want to display your hierarchy. This approach has the benefit, that you can "easily" test/debug your transformation. Now bind your TreeView to the calculated hierarchy without obscure experiments. If properties in your ViewModel (you mentioned IsConfigurable or whatever) change, you know when to re-calc your bound hierarchy.

Access Elements inside a DataTemplate... How to for more than 1 DataTemplate?

I've got 2 DataTemplates defined for a Listbox Control. 1 Template is for the UnSelected State and the other one is for the Selected State(showing more detail than the UnSelected State).
I followed the example here:
Link
about how to access the Elements inside the DataTemplates from Code behind.
I get it right, but it only finds and returns an element of the UnSelected DataTemplate. But when i search for an element in the Selected DataTemplate i get a NullReferenceException.
What could i be doing wrong?
Setting keyboard focus might be one reason you need to access the datatemplate elements. MVVM will not solve that issue and the FocusManager doesn't set keyboard focus.
What you are doing wrong?
I would say what you are doing wrong is trying to access elements inside the DataTemplate from code-behind. Naughty, naughty!
All joking aside, 99.9% of the time I see someone trying to access an element inside a DataTemplate from code, it is because their application is poorly designed, with no (or few) bindings and no view model at all. Many beginners tend to store their data directly in UI elements rather than using a view model. I think it is because their minds have been corrupted by experience VB, WinForms, and ASP.NET where it was the "normal" way to do it. There are a thousand reasons to use a view model and bind your data instead of storing them in UI elements. Look up "model view view model" online for more details.
Now to answer your question:
Any given ListBoxItem can only have one DataTemplate at a time. This is because its ContentPresenter has only one ContentTemplate property, and this property cannot have two different values.
Because of this, the visual tree under a ListBoxItem will always be generated from one a specific template, not a combination of several templates. If you change the ItemTemplate of the ListBox or otherwise update ListBoxItem.ContentTemplate, the visual tree produced by the old template will be thrown away and a new one built.
Let me say that again: If you change data templates, the visual tree produced by the old data template will be thrown away and a new visual tree built.
You can have a hundred data templates defined and usable on a given ListBoxItem, but only one at a time can have a visual tree instantiated for it. And these are the only elements that actually exist as part of the visual tree. All other templates exist only as templates - there are no actual elements created for them.
To put it another way: It is meaningless to ask about how to find elements in two different visual trees instantiated by two different templates on the same control, because a single control cannot have two different templates active at the same time.
Hope this clears things up for you.
Final advice: Do read up on MVVM, and stop trying to access elements inside DataTemplates ASAP. However if you think you might be in that 0.1% who actually do have valid reasons to access elements inside templates, write back with your actual reason for wanting to do so and maybe I can provide further guidance.

WPF: How to use views like ICollectionView and IEditableCollectionView

I understand the syntax but not how really to use it. It's clear in many basic scenarios but as soon as it get's a little bit advanced I start getting a headache.
For example there are many different views but often not clear wich one to use. Also should you use always just one or mix and match. Do you use the view as your itemssource for ItemsControls?
I'm gonna give a scenario. I have items from a database that I need to show info about in a app and also allow to edit and add new. The items form a hierarchy and the models are of different types. So the top level have children and they then have children.
I could show it in a TreeView or some itemscontrol. Problem here is I tend to bind to the children property of the root elements wich returns a List of chilren. Now the children aren't really inside a view, like I can't call editview.addnew() or filter the children straight away. Question is how do I ensure the children are also in a view and their children and so on. Should the model return a view, should I create a seperate view for each children type or even for each parent?
Another thing is if I'm allowing editing should I put the Collections straight into a IEditableCollectionView or wrap it in ICollectionView first (why is that better)?
Is there a good guide to using views that isn't just pure basics?

In wpf treeview, how to redraw the nodes with their previous expanded values(using MVVM)

I am developing a wpf desktop app with strict MVVM pattern.
Current my app is doing following things:
Showing a Treeview with HierarchicalDataTemplate.
User can expand or collapse Nodes.
User can add add new Nodes(Drag n Drop + double click).
Everytime a new Node is added Model is updated and Treeview is recreated based on Model.
Because Treeview is recreated, all nodes are shown as expanded after adding nodes.
I want to show nodes with their previous expanded condition. Is there any way to do this using MVVM ? What I have thought so far is
Model should not contain any data related to how to draw UI ??
VM should just get data from Model and put it in UI(and pass date from UI to Model) ??
Thanks for your thoughts. I may be way far out form rail. But just want to have some wisdom from you guys.
Thanks
PAIJA
If you haven't already, read this great article by Josh Smith: Simplifying the WPF TreeView by Using the ViewModel Pattern
Basically what he suggests there is to include a property called IsExpanded in your VM and bind the TreeView to it correctly so that the expanded/collapsed status is entirely controlled by the programmer.
One solution what I think could be is to stop the recreation of the tree, just update the model and only add nodeitems to the current node where you are dropping them. Just refresh the collections in model and dont refresh the tree. Let us know if this does't suits your architect.
Thanks,
Jagdev Josan
The view model can contain view related information, that is what it is for. It is a bridge between pure business and pure view. My view models usually expose a few business properties of an object and add a few related view properties. If all you need is business properties, then bind straight to the business layer. Its only when you need to do something like your situation here that you need a view model.
If you want to completely recreate the tree (which sounds crazy) you can store the expanded state of the nodes in your view model and bind them to the tree view items using an ItemsContainerStyle. that way when you recreate your tree view your previously expanded nodes will still be expanded.
So your wrapped business objects will contain an extra property IsExpanded that you can use to restore your tree view state.
P.s. did i mention its a bit over the top to recreate the tree view?

Resources