Logo
programming4us
programming4us
programming4us
programming4us
Home
programming4us
XP
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server
programming4us
Windows Phone
 
Windows Phone

Programming Windows Phone 7 : Items Controls - Sorting

- Free product key for windows 10
- Free Product Key for Microsoft office 365
- Malwarebytes Premium 3.7.1 Serial Keys (LifeTime) 2019
5/17/2011 4:45:19 PM
In earlier displays of these students, I used the property of Student called FullName to display the student’s name. You may have noticed that the students.xml file was actually sorted by this property, and that’s the order in which the students appeared on the screen. Popular email programs display your contacts sorted by first name, so I figured it wasn’t entirely a bad thing.

But in the most recent DataTemplate, I switched to using the LastName, FirstName, and MiddleName properties, and the unsorted display now looks very strange and just plain wrong.

How can this be fixed?

One approach is through code. It’s possible for the StudentBodyPresenter class to re-sort the data after it’s been downloaded. But you might prefer a more flexible approach. Perhaps your application needs to display data using different sort criteria at different times.

You can do that—and you can do it entirely in XAML—using a class called CollectionViewSource defined in the System.Windows.Data namespace. You’ll use this class in conjunction with a SortDescription class defined in the System.ComponentModel namespace. Besides the reference and XML namespace declaration for the ElPasoHighSchool library, you’ll need an XML namespace declaration for System.ComponentModel:

xmlns:componentmodel="clr-namespace:System.ComponentModel;assembly=System.Windows"


The whole CollectionViewSource can go in the Resources collection:

<phone:PhoneApplicationPage.Resources>
<elpaso:StudentBodyPresenter x:Key="studentBodyPresenter" />

<CollectionViewSource x:Key="sortedStudents"
Source="{Binding Source={StaticResource studentBodyPresenter},
Path=StudentBody.Students}">
<CollectionViewSource.SortDescriptions>
<componentmodel:SortDescription PropertyName="LastName"
Direction="Ascending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>

</phone:PhoneApplicationPage.Resources>


Notice how the Source property of the CollectionViewSource now references the Students property of the StudentBody property of the StudentBodyPresenter. This Students property is of type ObservableCollection<Student>. The Source of CollectionViewSource must be a collection.

The SortDescription object indicates that we want to sort by the LastName property in an ascending order. Since this LastName property is of type string, no additional code need be provided to support sorting.

The Binding can now be removed from the DataContext of the Grid, and the Source property of ItemsControl can now reference the CollectionViewSource resource:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
<ScrollViewer>
<ItemsControl ItemsSource="{Binding Source={StaticResource sortedStudents}}">
. . .
</ItemsControl>
</ScrollViewer>
</Grid>


And now the display looks more alphabetically comforting:



You can have multiple SortDescription objects in CollectionViewSource. Try this:

<CollectionViewSource x:Key="sortedStudents"
Source="{Binding Source={StaticResource studentBodyPresenter},
Path=StudentBody.Students}">
<CollectionViewSource.SortDescriptions>
<componentmodel:SortDescription PropertyName="Sex"
Direction="Ascending" />
<componentmodel:SortDescription PropertyName="LastName"
Direction="Ascending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>


Now all the women are first, followed by the men.

Or alternatively, perhaps you want to display the names of the male students in PowderBlue and the female students in Pink. It’s a rather antiquated convention, to be sure, but we are dealing with students who attended high school nearly 100 years ago! Regardless of the propriety of pink and blue, how would you do it?

Fortunately, the Student class has a property named Sex, which is set to a text string, either “Male” or “Female.” Since we’re dealing with data bindings in the DataTemplate, the obvious solution is a data converter, and fortunately the Petzold.Phone.Silverlight library has one that seems ideal:

Example 1. Silverlight Project: Petzold.Phone.Silverlight File: SexToBrushConverter.cs
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;

namespace Petzold.Phone.Silverlight
{
public class SexToBrushConverter : IValueConverter
{
public Brush MaleBrush { get; set; }
public Brush FemaleBrush { get; set; }

public object Convert(object value, Type targetType,
object parameter, CultureInfo culture)
{
string sex = value as string;

switch (sex)
{
case "Male": return MaleBrush;
case "Female": return FemaleBrush;
}

return null;
}

public object ConvertBack(object value, Type targetType,
object parameter, CultureInfo culture)
{
return null;
}
}
}


Like all data converters, it derives from IValueConverter and has two methods named Convert and ConvertBack. This converter also defines two properties named MaleBrush and FemaleBrush. These properties let us avoid hard-coding brushes in the code. The Convert method is the only one that’s implemented: If the value coming in is “Male” it returns MaleBrush and if “Female” it returns FemaleBrush.

Let’s put everything into one project. The StudentBodyItemsControl project has a reference to the Petzold.Phone.Silverlight library as well as ElPasoHighSchool. The Resources section instantiates the StudentBodyPresenter, the CollectionViewSource for sorting, and the SexToBrushConverter:

Example 2. Silverlight Project: StudentBodyItemsControl File: MainPage.xaml (excerpt)
<phone:PhoneApplicationPage.Resources>
<elpaso:StudentBodyPresenter x:Key="studentBodyPresenter" />

<CollectionViewSource x:Key="sortedStudents"
Source="{Binding Source={StaticResource
studentBodyPresenter},
Path=StudentBody.Students}">
<CollectionViewSource.SortDescriptions>
<componentmodel:SortDescription PropertyName="LastName"
Direction="Ascending" />
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>

<petzold:SexToBrushConverter x:Key="sexToBrushConverter"
FemaleBrush="Pink"
MaleBrush="PowderBlue" />
</phone:PhoneApplicationPage.Resources>

In the markup below I use five TextBlock elements to display the student’s name—LastName, FirstName, and MiddleName with a comma and a space—and at least four of them need bindings targeting the Foreground property from the Sex property of the Student object, using this SexToBrushConverter. This same binding needs to be repeated four times.

Or, perhaps we can simplify the markup just a bit by enclosing all five TextBlock elements in a ContentControl. If the Foreground property on the ContentControl is set with a single binding, then the same property will be applied to each TextBlock based on property inheritance. That’s what’s done in the following DataTemplate, which is otherwise the same as the one you just saw:

Example 3. Silverlight Project: StudentBodyItemsControl File: MainPage.xaml (excerpt)
    <ScrollViewer>
<ItemsControl ItemsSource="{Binding
Source={StaticResource sortedStudents}}">
<ItemsControl.ItemTemplate>

<DataTemplate>
<Border BorderBrush="{StaticResource PhoneAccentBrush}"
BorderThickness="1"
CornerRadius="12"
Margin="2">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>

<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>

<Image Grid.Row="0" Grid.Column="0" Grid.RowSpan="2"
Source="{Binding PhotoFilename}"
Height="120"
Width="90"
Margin="6" />

<ContentControl Grid.Row="0" Grid.Column="1"
HorizontalAlignment="Left"
VerticalAlignment="Center"
Foreground="{Binding Sex,
Converter={StaticResource sexToBrushConverter}}">

<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding LastName}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding FirstName}" />
<TextBlock Text=", " />
<TextBlock Text="{Binding MiddleName}" />
</StackPanel>
</ContentControl>

<StackPanel Grid.Row="1" Grid.Column="1"
Orientation="Horizontal"
VerticalAlignment="Center">
<TextBlock Text="Grade Point Average = " />
<TextBlock Text="{Binding GradePointAverage}" />
</StackPanel>
</Grid>
</Border>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</ScrollViewer>
</Grid>


Adding the color is worth the effort, I think:


Other -----------------
- Items Controls : Fun with DataTemplates
- Items Controls : Databases and Business Objects
- Items Controls : Binding to ItemsSource
- Items Controls : ListBox Selection
- Items Controls : Customizing Item Displays
- Items Controls and Visual Trees
- The Two Templates : Custom Controls
- The Two Templates : The Ever-Handy Thumb
- The Two Templates : Variations on the Slider
- The Two Templates : Custom Controls in a Library
 
 
Top 10
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 2) - Wireframes,Legends
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Finding containers and lists in Visio (part 1) - Swimlanes
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Formatting and sizing lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Adding shapes to lists
- Microsoft Visio 2013 : Adding Structure to Your Diagrams - Sizing containers
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 3) - The Other Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 2) - The Data Properties of a Control
- Microsoft Access 2010 : Control Properties and Why to Use Them (part 1) - The Format Properties of a Control
- Microsoft Access 2010 : Form Properties and Why Should You Use Them - Working with the Properties Window
- Microsoft Visio 2013 : Using the Organization Chart Wizard with new data
 
programming4us
Windows Vista
programming4us
Windows 7
programming4us
Windows Azure
programming4us
Windows Server