How to span multiple rows in a listbox - wpf

I have created a custom control that displays a composite collection on a grid panel. It looks something like this:
The 'slots' behind are a uniform 1 row apart and span 1 row each. The 'items' on top can be created at any row and can span multiple rows.
I would like to implement the functionality of SelectedItems from the Selector class on the first collection of 'slots'.
Can I derive from Selector (e.g., a listbox) and still create something like the second collection overlayed over the first?

Don't use a composite collection. Create a base class or interface and make a single collection of that type. Then extend that class or implement that interface in each of your various different objects that you want to display. Now you'll be able to add each of them into your single collection and just use a normal ListBox with SelectionMode = SelectionMode.Extended or SelectionMode = SelectionMode.Multiple.

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.

WPF: DataGrid with a tree-column in an MVVM Windows application

Here is a rephrased version of my issue:
Here is a screenshot of the result I'm looking for (from an older, non C#/WPF version of the application):
Looks like all the other grid-tree-views and what ObjectListView provides. But unfortunately I have some rules I have to follow:
WPF
MVVM
Just a DataGrid and its components must be used (no TreeView, ListView, etc.)
The Items are hold in an ObservableCollection<T> where T.Property1, T.Property2 etc hold the data for the columns of the DataGrid.
The lower Levels of an item are hold in T.PropertyChilds of type ObservableCollection<T> and are not known/filled beforehand. They must be loaded on the first exand of the item.
Here is a screenshot of similar data and what I've got so far in WPF/C#:
It looks like a standard DataGrid. But which columns it can hold, which property of T the columns are showing, which columns are currently visible, etc is defined by a own framework around the DataGrid which basically just adds columns to the public ObservableCollection<DataGridColumn> Columns Collection of a System.Windows.Controls.DataGrid.
My task is now to do a new class derived from DataGridColumn which can display and load the hierarchical data structure of my ViewModel described above.
The main problems I'm facing are as far as I can tell:
- how to visibly display the levels like a treeview in a DataGrid column
- how to process the loaded data from childs so they are shown as in the first screenshot above. Do I have to do a flat ObservableCollection<T> where I add the loaded ChildData and some extra properties like level and parent - or is it possible to define a kindo of a hierarchical data template for a DataGrid?
Thanks a lot
Soko

Can WPF CollectionViews be created to bring together multiple columns of data

I have about a dozen ObservableCollections that hold objects which have dates, singles and integers. All collections are of the same length and have data added and removed at the same time. One of the ObservableCollections is the main one and is needed when referring to the others.
Is there a way to use CollectionViews to bring 2 of these ObservableCollections together in such a way that they look like one ObservableCollection having the total of all of the original columns when data bound to a datagrid and/or chart? If so does anyone have an example?
Everything I have found shows the data from both sources being brought together by adding one on top of the other in what I would call a stack of data .
Thanks
Not pretty but I have a similar application.
Have a class with 5 base properties then a variable number of fields.
The fields I put in a List.
Can bind rows to a collection but not columns.
So I use a ListView Gridview where I build up the columns in code behind.
Bind the columns to Field[0], Field[1], ...
In you case you could have base class Bclass with the base Properties and a Property List
In your List<Fields> you just iterate the properties of the List<ExtensionClass>
Clearly the List<Bclass> needs to all have List<Extension> class with the same length in every item of the binding breaks.

Edit collection in separated ListBoxes

I have source elements like this:
var collection = new ObservableCollection<SourceItems>(source);
source implements INotifyPropertyChanged
I need to edit and view this collection in CheckListBoxes (listBox with checkBoxes from WPFToolKit)with rules:
every CheckListBoxes must be sort by one of collection's field. Collection has order field for each CheckListBox. For example - ItemOrder.
visible elements in one listBox depend on checked items from other.
Every CheckListBox has itemsSource
checkListBox1.ItemsSource=collection;
So, if i check items in one listBox i must see only checked items in other.
And every listBox must be sorted by one of source's field
listBox1 by field orderItem
listBox2 by field orderVisibleItem and so on.
User can move elements in each listBoxes and it must not affect ordering in other.
I tried create CollectionViewSource for every ListBox. But when I sort one, it sort each other.
Linq for filtering and sortnig don't work too, because changes not updating dynamicly.
Is there best way to create such functionality?
You should use CollectionViewSource.
I'm guessing that you used CollectionViewSource.GetDefaultView(.. ) ? you should create two NEW views for the collection:
CollectionViewSource cvs = new CollectionViewSource() { Source = TheCollection };

Items control data source's item property update, not reflecfted in the items control's itempanel template instance

I have a custom panel control that is intended to be used as an itemspaneltemplate in a items control.
The itemscontrol will be databound to a data source.
This datasource is a List, and each item in the list is a custom business object.
In the application, the user is able to update each of these business objects in the list, and that fires the notification on property changed as expected.
Now my problem is here:
When the user updates the object's properties in the data source (the itms in the List) that the items control is bound to, my custom panel control is not able to get that notification, so as a result the items control does not get updated with the updated items in its view.
I tried using an ObservableCollection instead of List - the problem is still the same.
I must be missing something fundamental here... please help with any pointers, answers or solution.
Change notification in a collection is a bit tricky. Say you have a collection of Products. you can implement change notification is three different places.
Change notification in the Product class (implementing INotifyPropertyChanged in class Product)
Change notification in the collection itself (i.e. using ObservableCollection)
Change notification in the class that holds the collection, that is, implementing INotifyPropertyChanged on the class that contains the collection. (usually this would be the ViewModel under MVVM)
Those tree ways are not the same, and each is for a different situation.
Let's say that the collection is ObservableCollection<Product> Products {get;set;}
if you want changes in the product to register (i.e., if you're doing something like Products[0].Name = "New Product"; then #1 is the right one.
If you want to do Products.Add(new Product(...)) then #2 is the right one.
If you want to do Products = new ObservableCollection<Product>() then #3 is the correct one. This is especially tricky since i'm not changing the collection, but creating a new one, so the ObservableCollection won't help - I'd need to implement INPC in the containing class.

Resources