问题
I have ObservableCollection
that contains a custom object.
Normally the items get added at the end of the list
What i am looking for:
- Items being added from the beginning of the list.
- This may only show in the UI, my entire program is already using the positions of data inside this list. So the objects inside it may not change order in the code behind.
This ObservableColection
holds Button objects (custom styled). These buttons are being displayed in a ListBox
and inside a StackPanel
with Horizontal layout (so the buttons get nicely placed after each other).
Problem:
Every button that gets created receives a DateTime
. A newly added button always has a more recent date then the button before that. All the calculations for this are happening inside a timer(currently running every second).
So i am basically sorting on this time, but after like 3 buttons suddenly a button gets placed at right hand side (instead of the left hand side).
For example:
Btn3: 14:15:45(correct) Btn4: 14:16:00(wrong) Btn2: 14:15:32(correct) Btn1: 14:04:17(correct)
The first 3 buttons get added properly at the beginning of the list each time. And suddenly the fourth item is being added at the second place. It seems it is not always comparing the time? Every time a button gets created the CollectionViewSource
method gets called upon.
Is there something wrong with the CollectionViewSource
or is there a better way of handling this?
回答1:
For grins would you try the sort in XAML? I know these are not the same names but this is from working code. I am not sorting on date but I have done hundreds of adds and removes from DocProps and the sort does not break.
<ListBox.DataContext>
<CollectionViewSource Source="{Binding Path=DocProps}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="Date" Direction="Desc" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
</ListBox.DataContext>
My other thought is that it may be sorting a string representation of date and getting it wrong. Maybe create an index 001 - 00n to sort on.
I added a date to this collection and it worked from me. But had to make the date a sortable format.
Text="{Binding Path=Date, Mode=OneWay, StringFormat={}{0:s}}"
回答2:
If I understood well, I would use the Ticks
property of DateTime
to sort because it is very accurate by its nature and of cource is a simple number.
回答3:
does your ICollectionView is an instance field or a local variable like in your codesnippet?
it has to be an instance field, then you sorting will work. btw i tried your snippet and changed the icollectionview to a field and it works.
回答4:
If you follow the link Siva posted in the comments and follow another link from there, you'll eventually end up at http://connect.microsoft.com/VisualStudio/feedback/details/592897/collectionviewsource-sorting-only-the-first-time-it-is-bound-to-a-source where somebody posted a workaround. This workaround is written for DataGrid but you can tweak it for whatever control you happen to be using:
Posted by Greg Bachraty on 2/28/2011 at 6:50 AM
Implement your own DataGrid:
public class SDataGrid : DataGrid
{
static SDataGrid()
{
ItemsControl.ItemsSourceProperty.OverrideMetadata(typeof(SDataGrid), new FrameworkPropertyMetadata((PropertyChangedCallback)null, (CoerceValueCallback)null));
}
}
The only thing coerce callback does in the current implementation is clear the sort descriptions. You can simply "cut" this code by overriding metadata. Not viable on Silverlight: OverrideMetadata API is not public. Though I'm not sure Silverlight is affected by this bug. Other risks and side effects may apply.
来源:https://stackoverflow.com/questions/10413535/reverse-order-of-observablecollection