1
votes

I am binding a ListBox in my MainPage to a collection of images that have been taken using the CameraCaptureTask. Everything is working correctly, although I would like to be able to change the sort order from Ascending to Descending when respective RadioButtons in my SettingsPage are checked. I have created a value in IsolatedStorage that remembers which RadioButton is checked, so that when the MainPage of my application loads, the ListBox's binding collection will be sorted and displayed accordingly. The actual sorting of my collection, however, is where I am having issues. Note, which each image in the collection, a DateTaken property is also saved.

MainPage.xaml

<ListBox x:Name="Recent" ItemsSource="{Binding Pictures}" Margin="8" 
                     SelectionChanged="recent_SelectionChanged"
</ListBox>

Now, in my Constructor I am setting my DataContext equal to PictureRepository.Instance, which is actually populated with the images from IsolatedStorage. I am not sure where or how to change the sort order of the collection before binding. I am thinking that in fact I would probably want to bind a copy of the sorted list, and in fact not change the sort order in IsolatedStorage. I was attempting to do something of the following as referenced from Sorting Listbox Items by DateTime values

MainPage.xaml.cs

public MainPage()
    {
        InitializeComponent();

        DataContext = PictureRepository.Instance;
        //Determine which Sort Radio Button has been Checked and display collection accordingly
        //Also not sure if this should be performed in the OnNavigatedTo event
        if (Settings.AscendingSort.Value)
        {
            //PictureRepository.Instance.Pictures.OrderBy(p => p.DateTaken).First();
            //DataContext = PictureRepository.Instance;
            var items = Recent.Items.Cast<CapturedPicture>().OrderBy(p => p.DateTaken).ToArray();
            if (Recent.Items.Count != 0)
                Recent.Items.Clear();
            Recent.Items.Add(items);
        }
        else
        {
            //PictureRepository.Instance.Pictures.OrderByDescending(p => p.DateTaken).First();
            //DataContext = PictureRepository.Instance;
            var items = Recent.Items.Cast<CapturedPicture>().OrderByDescending(p => p.DateTaken).ToArray();
            Recent.Items.Clear();
            Recent.Items.Add(items);
        }
    }

Neither option has worked, although admittedly I have never tried sorting an ObservableCollection before populating a ListBox before. Any links, assistance, or advice would be greatly appreciated in learning this concept!

1
Your DataContext is 'PictureRepository.Instance', your ListBox is binding to 'Pictures' and you are sorting a property named 'Recent'. At what point are you trying to set the ItemsSource of the ListBox to be the sorted items?Shawn Kendrot
I would like to set the sorted items immediately, based upon which RadioButton is selected in the SettingsPage. PictureRepository.Instance returns the Pictures ObservableCollection from the model, and Recent is the ListBox which the collection is bound to.Matthew

1 Answers

1
votes

I prefer to use CollectionViewSource when sorting a ListBox. Instead of changing the backend collection that you are binding to, you allow the controls to handle this.

You page xaml:

<phone:PhoneApplicationPage.Resources>
    <CollectionViewSource x:Key="PicturesViewSource" Source="{Binding Pictures}">
        <!-- Add for design time help. This object should return a collection of pictures
        <d:Source>
            <viewModels:MyFakeObject/>
        </d:Source>
        -->
    </CollectionViewSource>
</phone:PhoneApplicationPage.Resources>

<Grid>
    <ListBox ItemsSource="{Binding Source={StaticResource PicturesViewSource}}"/>
</Grid>

In your page you can modify how the ColletionViewSource is sorted by adding or removing SortDescriptions. You would do this whenever the user changes the radio button.

PicturesViewSource.SortDescriptions.Clear();
PicturesViewSource.SortDescriptions.Add(new SortDescription("DateTaken", ListSortDirection.Descending));