WPF ListView Grouping - with a twist - wpf

I have a treeview right now with a templateselector. Basically each tree node on the root is a "category" of some type of data and each child node under those are displayed in a specific way (via the template selector).
This allows me to show different data in a single control easily just using binding. My problem is that it's not working out so well visually. I would like to have a grid style (ListView.GridView) under each root node.
I was looking at ListView grouping but is it possible to define different columns for each group? Since I doubt that is possible, what are some options? I would like to allow the user to expand and collapse the groups just like a treeview but see a GridView under each node with scroll bars, etc.

I don't think that ListView supports different headers in groups. It's just grouping of rows. Looks like you're going to have to create a new ListView under each tree node. You might try a data grid. In WinForms you can bind to multiple tables and the grid will group by table which can be expanded and collapsed which would in effect show different columns. If you're using MVVM (I assume some collection or hierarchy model) I have no idea how you'd accomplish that with a data grid.

You may achieve what you want relatively simple if you adopt the MVVM architecture.
Each node on the tree is of a certain type (ViewModel). Each data type would be bind to a specific View. Each View can be a ListView with any columns you want.
I recommend you read about MVVM and adopt it in order to achievewhat you need. I found that the adoption of MVVM leads to applications with a much cleaner architecture and code.

Related

Fixed Document Tables?

I am looking for a layout control or other means of laying out data in a tabular format on a Fixed Document for reporting. I have used MigraDoc quite extensively in non WPF projects and its table object allows for a granular layout for each piece of data to be displayed in the table. Borders can be turned off on the cell level, columns can be merged/spanned, etc. Are there any controls that offer this kind on control within WPF? I have not seen where the DataGrid or the Grid will do what I need... easily. My data is not bound as I need to have full control over how it is displayed. I am not using a flow document so I cannot use the table object that it offers. Anyone have any suggestions? For now, I have resorted to programmatically creating a Grid and then inserting a Border containing a TextBlock within each cell. There just has to be a cleaner way!
BTW - I am looking to use native WPF controls in this project which is the reason that I am not using MigraDoc.

Using the DragDropTarget with a traditional Grid

Silverlight 4 now provides controls to handle Drag and Drop actions. All the Target Controls seem to inherit from DragDropTarget Like so
public class MyControlDragDropTarget : DragDropTarget<TItemsControlType,TItemsContainerType>
.
.
.
A number of controls have pre-defined DragDropTargets including the DataGrid, ListBox, Panels
Which is all very well, but I want to drag and drop from a grid not a datagrid, and there is no pre-defined one for a normal grid.
I actually want to drag a given row from the grid, but without a Container Type for a Grid I cannot work out how to define a DragDropTarget control for the grid.
Only way I can think is instead of using a grid - I use a listbox (for which there is a DragDropTarget) and then place a StackPanel or Grid in each row (which has one row of 'n' columns)
Anyone got any ideas
Ta in advance
A "normal grid" is simply another form of panel, there is no need for specialised DragDropTarget for the Grid, the existing PanelDragDropTarget is sufficient for a "normal grid".
Its important grasp that the Grid does not support the concept of "rows containing cells containing UI elements". The rows and columns of a Grid are entirely equal and are defined purely for layout purposes. UIElement children of a Grid are laid out entirely independently of each other, there is no concept of a set of values belonging to either a column or a row that can be moved or operated on as a group (like picking up a row and dragging it).
Sounds like you have already got an answer for yourself, use the ListBox instead.
BTW, DragDropTarget isn't provided by Silverlight 4 but rather the Silverlight Toolkit. This is an important distinction because the current quality band assigned to DragDropTarget is "Experimental". You need to think carefully about this if you want to use such code in some production release of your own.

How to create List-like UserControl in WPF?

I want to create my own expandable/collapsable tree-like UserControl, which nodes are the Border elements with any content. And this control should have the single SelectedItem. When I select one of the nodes I want to see details information about selected item.
I've done the control's presentation and a piece of logic:
I can see all the tree of elements, collaps any node(s), select one of them and see details. But I can't do bidirectional binding. I.e. I want to have an opportunity to change fields in details panel and immidiately see changes in the tree-control.
Help me please either call force update (rebind data) of the control (just give a tip how to perform this) or give an advise how to create my own List-like UserControl.
I tried to make my control inherit from some ListBox class but I couldn't.
PS. Sorry for my bad English...
Use the TreeView control.

Subrows into a row in GridView using WPF & C#

In my gridview I need to aggregate subrows into each row, something like in p2p emule/amule application where you can do double click to each file you are downloading and then under it you can see the parts of the file from where you are downloading.
Is it possible in WPF?
Thanks.
You could do a few things:
Add some container (ie: another Grid or a StackPanel) to the Grid row. This would let you add multiple objects to the grid row. On your "double click" event, you could change the visibility to show those objects.
Use a TreeView with a HierarchicalDataTemplate, and treat this as hierarchical data. This is most likely the more "correct" approach. The Displaying Hierarchical Data sample on MSDN walks through the process of this.

using MVVM and WPF for a realistic visualizations

I currently need to create a visual representation of a ferry system that displays the actual ferries their position on the sea and the state of their cargo. The ferries contain trucks and the trucks contain cars. I need to display the actual trucks and their xy postion on the deck. When the ferries are loaded the postions of the trucks are updated frequently so the look animated. Also I need to display the actual cars on the trucks. Trucks, cars and ferries have some states that need to be displayed too. So I have a hierarchical structure of data that I need to visualize in a rather realistic manner.
What would be a good way to implement this kind of stuff in WPF? Should I use MVVM with one TreeView control and create a HierarchicalDataTemplates for sea, ferry, truck and car and a ControlTemplate for the TreeView? Or should I better use UserControls and compose and update them in code instead of databinding to observable collections of the ViewModel. Do you have any experience with this? How would you do this? Could you sketch out class/control setup?
I'd recommend making a "lookless" control as opposed to making user controls. Generally I use user controls as glue/container for my lookless controls. An example of a lookless control is the Button class. It contains a default style and in Blend, you can modify the style all you like. It also supports the visual state manager so you can change how the presentation looks when states change. You can think of the codebehind of a lookless control as a mini ViewModel. Here it is ok to mix some presentation stuff and your domain classes.
If you follow this same design, you could create a Ferry lookless control. This control would have a set of it's own dependency properties (possibly listening to the OnChange of the DP).
Your Ferry control may have an ObservableCollection DP called "Trucks".
Then in your Themes\generic.xaml, create a default style for your Ferry control. Your default style may have an ItemsControl with an ItemsSource={TemplateBinding Trucks}. The ItemsControl panel template, could be your own custom panel for arranging the Trucks, or maybe you use a Canvas. For the ItemsControl items template, you would have something like this:
<DataTemplate>
<mynamespace:TruckControl/>
</DataTemplate>
You Truck control, would also be a lookless control with it's own default style, and it's data context will already be set, so you can directly do the {Binding Path=xyz}. Your Truck control could also set it's Canvas.Left/Top (if you chose to use a canvas in the pervious items control..or maybe it doesn't set its position at all if you made a custom panel for it) or a render transform as to put it at the correct X,Y. You could also use the items control in the truck's template to render out the cars in the same fashion you rendered out the trucks in the ferry control. Also its possible to create states for the VisualStateManager as to make it fully Blend supportable. So if a truck goes into a "problem state" you could easily style that state in blend to make it blink red, for instance.
I know it sounds like a lot to digest, but in the end having stylable controls all supporting an MVVM model will make your life 1000000x easier.
I'd suggest studying Microsoft's silverlight toolkit to get a good idea how to do lookless controls and such. Try looking at a simple control, like the DatePicker ( http://silverlight.codeplex.com/SourceControl/changeset/view/25992# ) One caveat is ignore DatePicker.xaml file (it's just a mirror of what gets put in generic.xaml and nothing bad would happen if you just deleted it).
The things you should pay close attention to are:
1.) The attributes on the class. These help Blend know how to deal with your control.
2.) The OnApplyTemplate override. This is where you can pull out specific elements from your template. These are known as "parts" and you will see the parts tab in Blend. The attributes in #1 can define what "parts" are in the template and what type they are expected to be.
3.) The DefaultStyleKey = typeof(...) in the constructor. This tells Silverlight what default template to use in the generic.xaml
4.) Look at Themes\generic.xaml. This is a special hardcoded file location that stores all your default templates. Search for the DatePicker style and you will get the idea :)
Good luck!
I just wanted to let you know, how I actually implemented it. It turned out that it was not necessary at all, to write custom controls or UserControls for this. All I did, was writing datatemplates for the car, ship, ferry, truck etc ViewModels. For example the datatemplate for the FerryViewModel contained an ItemsControl with a ItemsPanel of type Canvas (to be able to position the trucks) and an ItemTemplate that was a DataTemplate for TruckViewModel. A very simple and fast approach.
I'd suggest having one user control handle all the drawing. Otherwise you can get lost the the hierarchy of objects. Also it makes it easier if another item was added, say people in cars, trucks and ferries.
If your model is hierarchical then you can just pass in the top level into the control, and let the control sort itself out.
MVVM works well for existing controls, but existing WPF controls only work if there's a control that's close to what you need, and with a few tweaks would work. I can't think of a standard control in WPF that's close to what you need, so it's time to write a new control.
WPF works really really well with view models. If you can keep code behind away until specifically needed then you can separate ui from data so much more easily. It will allow your ui's to be some much more upgradeable if the data model doesn't change between different display.

Resources