Sorting WPF Datagrid - wpf

Good morning at all.
In my WPF application I have a datagrid, with various columns. One of these is like a button, when the user click on that button cell the row move on top of datagrid (like a Pinned items). This operation in done by a command and a redefinition of sorting like this:
phrasesView = CollectionViewSource.GetDefaultView(MyCollection);
phrasesView.SortDescriptions.Clear();
phrasesView.SortDescriptions.Add(new SortDescription("IsPinned", SortDirection = ListSortDirection.Descending));
phrasesView.Refresh();
This work's fine.
Now if i want to sort for a second column such as 'Name' i want the sorting should be made by 'Name' and 'Pinned', maintaining the pinned element always on top of datagrid. I catch the Sorting event with a trigger and trasform it in a command, and in this command i made the same operation of the previous example, adding a new sorting condition ('Name' in this example).
phrasesView = CollectionViewSource.GetDefaultView(TargetCollection);
phrasesView.SortDescriptions.Clear();
phrasesView.SortDescriptions.Add(new SortDescription("Name", SortDirection));
phrasesView.SortDescriptions.Add(new SortDescription("IsPinned", SortDirection = ListSortDirection.Descending));
phrasesView.Refresh();
But the effect that i have it's a reorder only by name, and the pinned item don't remain on top. But after if i click on button's cell (the first sorting condition so to speak) the sorting work such as expected.
Were i make a mistake?
MyCollection it's an ObservableCollection
phrasesView is a CollectionViewSource of MyCollection
Thank you

Related

XamDataGrid sort in Reverse Order

I have xamdatagrid in which I Add Item, every time new item added it goes to the bottom. I want every time I add item it should be on the top row "like reverse sort"
also in field layout setting I am adding new record on top.
note: I removed sort option from field
Note: I dont want to sort by any field except by row insertion order if its in xamdatagrid.
or sort of list like list.reverse possibility in xamdatagrid.
Assuming you're binding your grid to an ObservableCollection, use the Insert(0, item) method.
You can also use a CollectionViewSource for your grid's data source and set the sort there, while calling Add(item) on your source collection normally.

WPF Data gird row selection change event from selection change event

I'm looking for a workaround to an issue I've noticed in a project that I'm working on. I have a datagrid bound to a list of a class I've created. Whenever a user types in a stock symbol in this datagrid I have the roweditending event set to pull in some information to populate the other fields in the datagrid.
This generally works fine, however I've noticed that the event doesn't fire in some instances. I'm going to try to explain this the best I can... upon data entry if I enter information into a cell and then click another row on the datagrid - focus doesn't shift to the new row but shifts to the row containing the cell I was just entering data into from that cell, then if I select another row or input element the row edit ending event doesn't appear to fire and as such my code to populate the rest of the row doesn't execute.
Everything else is fine, and it's a pretty subtle issue, only one path of input to make it happen, but I was wondering if anyone had run into this or found a work-around?
I've been looking at the selection change event, but I need to be able to grab the row that was selected. In the row edit ending event I use
Dim NewTrade As Trade = e.Row.DataContext
to get the instance of my class that the row represents and to add the additional fields.
I'm not sure I see a way to get the row and it's datacontext for the row I just shifted from using the SelectionChangedEventArgs.
Any ideas for a workaround?

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 };

How to remove items from an Observable Collection

I appologize for the novel but I wanted to explain as much as I have done thus far.
Within my current project I have an application that consumes a service that provides a collection as a <List>. Due to how I am using this data in the application I have had to convert this data to an observable collection. This was done so that as the data was selected and moved about the application UI updates would be refreshed using INotifyPropertyChanged and INotifyCollectionChanged.
Where I am having a challenge now is I have a listbox that is bound to the observable collection within the listbox I have a datatemplate that renders out the items of the collection. This data template contains a button which needs to allow the user to click the button for each item to remove them from the collection.
The use case for this is a listbox that stores selected name as chosen from a gridview. Once the user has selected names from the gridview they are stored ( within the observable collection as a queue) and rendered out in the UI in a listbox control which shows all selected names. I need to provide the user with the ability to remove these names in any order selected.
From what I have been reading there is no means to enumerate / index an observable collection. For situations such as this you should use List or an Array. However in order for the items to refresh in the list view they need to be in an Observable Collection.
From what I have read it appears that when the event is triggered I need to convert the observable collection to an Array and then evaluate the array to determine the index and then remove the record accordingly?
I think I may be off base on this as it seems like I am over engineering this problem? The above scenario does not seem correct is because I fell as if I am doing a lot of converting to and from the collections to just remove a record?
Does anyone know of an efficient means to remove records from a collection ( in any order selected) when the collection is rendered out as an items control within a listbox?
I’ve been successful in removing the last record added to the collection using RemoveAt() however I have not had any success in randomly removing records.
Afterthought: Part of this issue could be related to the fact that I have a button inserted within the datatemplate (control item) and as a result the item is not actually being selected before the event is fired on the button event?
Sorry for the rambling on this but I have had my head in this for hours and made minor progress. Any tips or ideas would be appreciated!
ObservableCollection<T> inherits from Collection<T> which implements IList<T>, so you can certainly index and enumerate it. It has a Remove method that takes the object to remove and removes the first occurrence in the collection and a RemoveAt method that takes an index and removes the item at that index.
Based on your afterthought, it sounds like you have a WPF ListBox with an ItemTemplate that creates a Button. ListBox will set the DataContext of each instantiated template to the item in the list being bound to, so you can get a reference to the item that created a Button from the DataContext property on the Button or by using a Binding.

Set selection to newly added Item in WPF TreeView

I'm using a TreeView to let the user navigate a complex data structure more easily. I'm trying to add a feature to my application so my users can add new items to the datastucture by clicking a button on a toolbar. This new item has 3 levels, each with 1 item. I would like to select the item in the lowest level.
Adding the data isn't a problem, I just add a new item to the collection that is bound to the TreeView in a specific. I can lookup the item by hand browsing the TreeView, so I know the adding works. Now, I want to set the selection of the new item programmaticly. So the user can change the default settings in the element right away.
I've done some testing and I've found that setting the selection is done with something like:
var obj = TreeView.ItemContainerGenerator
.ContainerFromItem(selectedObject) as TreeViewItem;
obj.IsSelected = true;
I've tried adding this code directly after my Add-method. The adding function returns the new object and places this in selectedObject. The Add-method adds a to an ObservableCollection, which raises the appropriate events.
But, obj is always null directly after adding.
I've tried setting the selection in the LayoutUpdated event, but in this case the obj variable from the earlier code always null again.
I think I might be missing something here. Does anyone have an idea on how to add a new item to the bounded collection and select that item in the TreeView?
You might want to read this article by Josh Smith on using the treeview in WPF. He demonstrates how to use an IsSelected property that could easily be adapted for your needs, using the MVVM pattern.

Resources