Display multiple lists at once in WPF ListView? - wpf

Let's say I have an indefinite amount of Branch objects and each one has a List with the employees of that branch.
I now want to list all employees of all branches grouped by their respective branch in one ListView element.
The only solution I come up with is to run through all branches, pull their employees and put them in a separate list which I then use as the ListView's ItemsSource. Is there an easier and/or more effective way?

If i understand correctly, you have a list of an object, and it has a other list in its properties. And you need sum of all inner lists.
See SelectMany
You can use it like
MyList.SelectMany(item=>item.OtherLists);
it gives you sum of all OtherList's elements.
For grouping, see GroupBy
and you can use it like that
Innerlist.GroupBy(item=>item.Id)
you should use GroupBy first, SelectMany later, based on your question, something like
Branches.GroupBy(branch=>branch.Name).SelectMany(item=>item.Employees)
and you can put them in a list(and bind them), or just set the ItemsSource.

Related

Order elements in view or in view model?

I am using the MVVM pattern and I would like to sort the elements on a datagrid. In my view model I have an ObservableCollection with the element for the datagrid.
In the datagrid I can sort element cliking in the column name, so that is nice, and for multiple columns. I like this feature.
However, I would like to do some more specific ordering, for example show first the element which the ColumnB has "valueC" and later the rest of the elements, and when I sort for a column name, order for that column but show first the elements with "valueC" and later the rest of the elements sorted by the column that I clicked.
To do that, I can sort the elements in the ObservableCollection of the view model, but I think that this functionality is more something that it would be done in view, plus because I would like to sort by columns, so I would have to say to the view the column that is clicked.
However, I don't know if it is posible to do this kind of complex sorts in the view, perhaps with some converter or with any way.
Thank so much.
Every logic has to be done in the ViewModel. View must not know anything about the logic behind displayed datas.
In a simple case you could order your items in a view but in a realistic case, ordering will not affect only visible items but it affects also items not shown because of the paging.

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.

Can you filter a single item from a CollectionViewSource

I want to filter out a single item in my CollectionViewSource
I already have other filters applied, but I'm trying to find a way of filtering out an individual item without having to call a function that iterates through all items.
Is this possible?
It's not exactly clear what you're asking, or what your concern is. Perhaps if you elaborate I could give a better answer.
However, as I see it, you have these options:
Don't include the item in the underlying collection (or have a separate collection that does not contain it) and base your collection view on that
Adjust your existing filter so that it excludes the object in question
Create another collection view over your existing collection view that filters out the item
If the item is in the underlying collection, how else could you reasonably exclude it but via the filter?

Custom sorting logic for groups using CollectionViewSource

I have a list of "stuff" which needs to be filtered then displayed in a grouped and sorted manner. The data needed to calculate the grouping and sorting order is not available as simple properties - there needs to be some work done in code to calculate the order and groups.
CollectionViewSource lets me define custom filter and sort logic - so far so good. It also lets me bind GroupDescriptions to a value converter so that I can generate the group names.
The last thing I want to do is control the order that the generated groups appear and this is causing me pain!
Everything I see about CollectionViewSource.SortDescriptions says that it will sort groups by a property name, but I don't have a property available to sort by. SortDescriptions can't be bound to a value converter like GroupDescriptions can and I'm out of other ideas.
So - how do you implement custom sorting logic of CollectionViewSource groups?
This post on Bea Stollnitz' blog, and the GitHub repo, demonstrates how you can do that. You will have to sort by the criteria of your grouping first. Even if this is not a concrete property, it should be possible to sort your items using the same logic that you use to group them, isn't it?! Certainly, this is not possible using a SortDescription instance, but you could instead use the ListCollectionView.CustomSort property and specify an appropriate IComparer implementation.

Array binding Xaml by Position on Datagrid

I have a list of string array as input. The array dimension are static for all the list but I can't know the array size until the list is retrieved.
I need to bind the list in a datagrid in Silverlight.
I tried to create columns at runtime, binding each column to a particular array position but cannot find a way.
Have you any idea how to do it?
I could eventually "convert" my list of array in anything else that could be binded in a datagrid?
The idea is to have a sort of 2d Matrix showed inside the datagrid in Silverlight (I think that the problem is similar).
List
column_1 column_2 column_3 .. column_m
string[1,1] string[1,2] string[1,3] .. string[1,m]
string[2,1] string[2,2] string[2,3] .. string[2,m]
string[3,1] string[3,2] string[3,3] .. string[3,m]
....
string[n,1] string[n,2] string[n,3] .. string[n,m]
n is list lenght, m is list column max number.
Any idea is appreciated
I've found two solution to the problem that use the schema in the Denis's answer:
the first one is to use reflection to generate a class at runtime for the binding as suggested in this article (thanks to Vladimir Bodurov). I've tested this solution and I'll try to use it on my project. The only problem right now is that for large collection, the performance are poor. But I hope that someone will fix it in next relese (Silverlight 3 seems to not have fixed this problem, yet)
the second solution will be using some dynamic language for generate data. I don't know if this could be faster or not (probably not) but eventually could help. I will try in the future and use ironpython or ruby to generate classes that will be binded in datagrid.
If anyone have tryed using the second solution or any performance related information about creating classes at runtime, it will be appreciated.
Giorgio
Unfortunately that's not gonna be easy.
Do you have any valid constraints, like the maximum number of columns that is allowed or anything like that?
If you do (let's say you have N column maximum), you might be able to do something by
Having a class that exposes N
properties (named Col1...ColN for
example) that map the content
of the array for one line at column
X
Generating a list of that class,
one instance for each line
Generating the correct number of
column on the fly, binding each
column to property ColX
Binding your DataGrid to that list
That's kind of ugly, but it would work.
If you do not have to rely on the DataGrid, there is a possibility using a UniformGrid. A UniformGrid is a panel that layouts its children in a regular grid (every item has the same width, every item has the same height). You can indicate the number of columns at runtime, and the panel will fit children one after the other up to the number of columns and then continue on another line.
You could bind an ItemsControl to your array, indicating it should use a UniformGrid as its layout panel and indicating a suitable ItemTemplate to render each string.
The second option is much easier, but you will not have the capabilities of the DataGrid like sorting, moving columns, row selection, edition events per row etc.

Resources