DataGrid and Cell-Level ComboBoxes - wpf

Scenario
ComboBox C depends on the selected value of ComboBox B, which depends on the selected value of ComboBox A. All of these ComboBoxes are in a DataGrid.
Common Road Blocks:
The User must be able to add new rows (This Requires a ItemsSource item type that has a parameterless constructor).
To access the database to populate the List of Available Options for the Comboboxes, the current project would require the Database Credentials/DataContext be passed into the Constructor.
Attempt 1
I've tried using 3 CollectionViewSources, one for each of the ComboBoxes (Concept Code Here), but the SelectedItem of the ComboBox gets automatically selected in the other DataGrid rows. I need to find a way to isolate the CollectionViewSource to each row.
I've considered just adding the CollectionViewSource data to each of the DataGrid Items so I can just bind to it that way, but I have to access the database to generate the CollectionViewSource.
I also tried not sharing the CollectionViewSource as seen in this question, but that destroyed the link between the 3 ComboBoxes, as well as the Rows. If I could just set the CollectionViewSources to be shared within each DataGrid Row and not between each of them, I think it would work. I just can't find a way to do that.
Attempt 2
I've looked at this question: How to get cell level ComboBox for WPF DataGrid?
This would work, but the User needs to be able to add rows to the DataGrid. The example code in that question also uses a parameterless constructor. I am in a situation where access to the database to populate the lists would have to be passed into the constructor.
The Question
How do I do this correctly?

Bind to a List or ObservableCollection, not a CollectionViewSource
CollectionViewSource tracks the Current Item, so changing the value in one ComboBox will change it in all ComboBoxes

Related

WPF ToolKit Datagrid :Ignore the newly added rows for sorting in a datagrid

The issue requires adding the custom sorting to the datagrid, where in it requires rows swapping based on the sort type i.e., ascending/descending.
Since we have the datatable binded to datagrid Itemsource, not able to get the right API’s associated with the datatable to move the rows across the datagrid unlike the IEnumerable which has API’s like Move to move the rows across different positions in the datagrid.
Tried conversion the datagrid Itemsource to ICollectionViewSource or IEnumerable, but not able to achieve what is needed.
Had refered the following link for reference:
https://social.msdn.microsoft.com/Forums/vstudio/en-US/72c57bc5-7181-4177-87fe-c838638777db/wpf-datagrid-sorting-add-blank-a-row-always-at-bottom-irrespective-of-sort?forum=wpf

Databinding when source changes from null to object array

I have an MMVM project and with one of my View/ViewModels have an issue with databinding.
The view consists of a few combo boxes, and the user is required to select a value from each combox box. After a value is selected, I need to populate the next combo box.
How can I ensure the databinding works correctly in WPF, since only the the first combo box's value is populated on load. The others are all null, and seem to break all databinding to those attached controls. I have INotifyPropertyChanged implemented on my ViewModel, but I think things are getting lost due to the initial null values.
I would use ObservableCollections for each ItemsSource.
Create a new instance of each collection before binding them to your ComboBoxes. Leave them empty, but instantiated so that they are not null.
Then, when you are affecting the content of each combobox, directly modify each collection respectively rather than rebinding the ItemsSource (though I assume you are not doing that since you are using MVVM).

How do I un-link the selection of two separate comboboxes which bind to the same object?

I have two seperate WPF Comboboxes both of them bind to the same object to populate their values. However, when I change the selection in one combobox, the selection in the other combobox is changed to the same as the first, and vice versa. This is not the behavior I want, I want only want to bind the content of the comboboxes to a single source without mirroring their selections. I am binding to a BindingList.To bind I use
ItemsSource="{Binding}"
and
comboBox1.DataContext = bindingList;
What do I need to do to unlink the selections of these two comboboxes?
The way these actually work bind the scenes is by wrapping the collection in an instance of ICollectionView, which maintains the current selected item (amongst other things).
To get the behaviour you want, just set the DataContext of each combo box to:
new ListCollectionView(bindingList);

DataGrid Sorting retention on ItemsSource Changed

I am using an MVVM approach.
I have a ViewModel and View called AllSomethingViewModel and AllSomethingView. The View Model contains a list of SomethingViewModels and a SelectedViewModel. The View contains a usercontol bound to the AllSomethingViewModel's SelectedVM property and a listbox control that lets me select a VM. Basically when I pick a new VM the usercontrol's DataContext changes and so the view associated with SomethingViewModel updates with new information.
SomethingViewModel contains a list of objects called ObservableCollection(DataPoints) data.
I have a DataGrid bound to data and columns defined that are bound to data's members. This works fine. I can change views and this datagrid updates and everything is nice.
The issue I am running into is that I would like whatever sorting is applyed to the datagrid to persist when the datacontext changes.
On the View associated with SomethingViewModel, I can subscribe to DataContextChanged event but I'm not sure what To do from there to get the sorting to apply.
For Example. I have 2 SomethingViewModels. So in my list there are 2 options. When i pick the first one I get my datagrid with my data. In the datagrid I decide to sort by DateCreated Ascending order. Then I go to my second VM, the datacontext changes so the data in the grid is updated but it is no longer sorted!
If your sorting is done by the DataGrid then it is stored in the ICollectionView that the DataGrid uses to display its data.
ICollectionView view = CollectionViewSource.GetDefaultView(myDataGrid.ItemsSource);
// Sorting is found in view.SortDescriptions
There's an example of setting your sorting in code here. Hope that's enough to get you going in the right direction

Append Items to Databound ItemsControl in WPF

I've got a Combo Box that is databound to an ObservableCollection of items. I would like to have a default selected item that is (None) that would set the value of the property I've bound to "SelectedValue" to null.
I think there ought to be a way to achieve this with some combination of Style/DataTemplate/TemplateSelector. I'm trying to design this with MVVM in mind, so I'd like something that doesn't use codebehind and is as reusable as possible. I'd also like the benefits of the ObservableCollection (updating the collection causing the control to rebind) to remain intact.
Bonus part B:
I would like to also be able to append an extra visual element to the bottom of an ItemsControl as well. I was thinking it would be easy to change the DataTemplate if I knew how to trigger it on the last item of a collection. Willing to entertain other options here.
The simplest way I've found to do this is to insert a "special" value into the underlying collection, and display the "(None)" text when it's selected. Obviously then you need to run your binding through a converter to take this value into account and return null when it's selected. (See this question of mine which was a result of me trying to add an actual null value to a ComboBox's underlying collection.)
Having said that, it might actually be possible to do what you want with the CompositeCollection class. You could make a separate collection (with only one item - your Null item) and bind your ComboBox to both it and your original collection through the CompositeCollection.

Resources