Reputation: 2249
I have problem with ordering data for ListView. I have EventDisplay class which is an ObservableCollection for ListView(called Events)
private ObservableCollection<EventDisplay> currentEvents = new ObservableCollection<EventDisplay>();
private void Events_Loaded(object sender, RoutedEventArgs e)
{
sv = (ScrollViewer)VisualTreeHelper.GetChild(VisualTreeHelper.GetChild(this.Events, 0), 0);
Events.ItemsSource = currentEvents;
}
I then add new data by function :
private void LoadDataToList(List<EventDisplay> newItems)
{
foreach (EventDisplay ed in newItems)
{
//Set some additional data
currentEvents.Add(ed);
}
//When this line below is commented ListView data is updated
//but is not sorted, when i uncomment the listview data is not being updated
//currentEvents = new ObservableCollection<EventDisplay>(currentEvents.OrderByDescending(x => x.ed.date).ToList());
}
So what is the proper way of ordering data for ListView in Windows 8.1 apps ?
Upvotes: 0
Views: 1200
Reputation: 5373
You can sort & filter the view of your ObservableCollection (explanation here)
public class ViewableCollection<T> : ObservableCollection<T>
{
private ListCollectionView _View;
public ListCollectionView View
{
get
{
if (_View == null)
{
_View = new ListCollectionView(this);
}
return _View;
}
}
}
Data structure for the example:
interface ICustomer
{
string CuctomerName{get;set;}
int Age{get;set;}
}
Example use of the code:
ViewableCollection<ICustomer> vCustomers = new ViewableCollection<ICustomer>();
// Sorting settings:
ViewableCollection<ICustomer> vCustomers.View.SortDescriptions.Add(new SortDescription("CustomerName", ListSortDirection.Ascending));
vCustomers.View.Filter = MyCustomFilterMethod;
// add data to collection
MyCustomers.ToList().ForEach(customer => vCustomers.Add(customer));
Examlpe filter method:
private bool MyCustomFilterMethod(object item)
{
ICustomer customer = item as ICustomer;
return customer.Age > 25;
}
when you need to refresh the filter, the only thing you need to do is call:
this.vCustomers.View.Refresh();
Then you bind your GUI to vCustomers.View
You don't need to reset binding sources etc.
Upvotes: 1
Reputation: 1048
You should do the following :
currentEvents = new ObservableCollection<EventDisplay>(currentEvents.OrderByDescending(x => x.ed.date).ToList());
Events.ItemsSource = currentEvents;
This forces the ListView to rebind to your new sorted observable collection.
Another option is to sort the Observable collection in place. However, it may introduce flickering as the ListView will constantly update as the sort progresses.
If you don't want the ScrollView to reset its position, you can save the scrollview position and then restore it after sorting the list. I've had success with Implementing a custom ObservableCollection that supports sorting but prevents UI flickering by suspending change notification during sort and then issuing a reset notification. The ScrollView should stay at its current position even when confronted with the reset event.
Upvotes: 1
Reputation: 7944
Use this for your add items code:
foreach (EventDisplay ed in newItems.OrderByDescending(x => x.ed.date).ToList()
{
//Set some additional data
currentEvents.Add(ed);
}
The reason your doesn't work is that you are reassigned the currentEvents
reference rather than updating the ObservableCollection
.
Upvotes: 1